Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • Download


RNS/Link.py 85d77c10a11ff0e943b100ef86fb5cbfa791c8b3 (85d77c10) Text, 72.36 KB

T8b949e# Reticulum License
T8b949e#
T8b949e# Copyright (c) 2016-2025 Mark Qvist
T8b949e#
T8b949e# Permission is hereby granted, free of charge, to any person obtaining a copy
T8b949e# of this software and associated documentation files (the "Software"), to deal
T8b949e# in the Software without restriction, including without limitation the rights
T8b949e# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
T8b949e# copies of the Software, and to permit persons to whom the Software is
T8b949e# furnished to do so, subject to the following conditions:
T8b949e#
T8b949e# - The Software shall not be used in any kind of system which includes amongst
T8b949e# its functions the ability to purposefully do harm to human beings.
T8b949e#
T8b949e# - The Software shall not be used, directly or indirectly, in the creation of
T8b949e# an artificial intelligence, machine learning or language model training
T8b949e# dataset, including but not limited to any use that contributes to the
T8b949e# training or development of such a model or algorithm.
T8b949e#
T8b949e# - The above copyright notice and this permission notice shall be included in
T8b949e# all copies or substantial portions of the Software.
T8b949e#
T8b949e# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
T8b949e# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
T8b949e# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
T8b949e# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
T8b949e# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
T8b949e# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
T8b949e# SOFTWARE.

Tff7b72from T7ee787RNST7ee787.T7ee787Cryptography Tff7b72import Te6edf3X25519PrivateKeyTb4b4b4, Te6edf3X25519PublicKeyTb4b4b4, Te6edf3Ed25519PrivateKeyTb4b4b4, Te6edf3Ed25519PublicKey
Tff7b72from T7ee787RNST7ee787.T7ee787Cryptography Tff7b72import Te6edf3Token
Tff7b72from T7ee787RNST7ee787.T7ee787Channel Tff7b72import Te6edf3ChannelTb4b4b4, Te6edf3LinkChannelOutlet

Tff7b72from T7ee787time Tff7b72import Te6edf3sleep
Tff7b72from T7ee787.T7ee787vendor Tff7b72import Te6edf3umsgpack Tff7b72as Te6edf3umsgpack
Tff7b72import T7ee787threading
Tff7b72import T7ee787inspect
Tff7b72import T7ee787struct
Tff7b72import T7ee787math
Tff7b72import T7ee787time
Tff7b72import T7ee787RNS
Tff7b72import T7ee787io

Tff7b72class T56d364LinkCallbacksTb4b4b4:
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8fflink_established Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8fflink_closed Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffpacket Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffresource Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffresource_started Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffresource_concluded Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffremote_identified Tff7b72= Tff7b72None

Tff7b72class T56d364LinkTb4b4b4:
T8b949e"""
This class is used to establish and manage links to other peers. When a
link instance is created, Reticulum will attempt to establish verified
and encrypted connectivity with the specified destination.

:param destination: A :ref:`RNS.Destination<api-destination>` instance which to establish a link to.
:param established_callback: An optional function or method with the signature *callback(link)* to be called when the link has been established.
:param closed_callback: An optional function or method with the signature *callback(link)* to be called when the link is closed.
"""
Te6edf3CURVE Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffCURVE
T8b949e"""
The curve used for Elliptic Curve DH key exchanges
"""

Te6edf3ECPUBSIZE Tff7b72= T79c0ff32Tff7b72+T79c0ff32
Te6edf3KEYSIZE Tff7b72= T79c0ff32

Te6edf3MDU Tff7b72= Te6edf3mathTff7b72.Td2a8fffloorTb4b4b4(Tb4b4b4(Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffMTUTff7b72-Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffIFAC_MIN_SIZETff7b72-Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffHEADER_MINSIZETff7b72-Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffTOKEN_OVERHEADTb4b4b4)Tff7b72/Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffAES128_BLOCKSIZETb4b4b4)Tff7b72*Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffAES128_BLOCKSIZE Tff7b72- T79c0ff1

Te6edf3ESTABLISHMENT_TIMEOUT_PER_HOP Tff7b72= Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffDEFAULT_PER_HOP_TIMEOUT
T8b949e"""
Timeout for link establishment in seconds per hop to destination.
"""

Te6edf3LINK_MTU_SIZE Tff7b72= T79c0ff3
Te6edf3TRAFFIC_TIMEOUT_MIN_MS Tff7b72= T79c0ff5
Te6edf3TRAFFIC_TIMEOUT_FACTOR Tff7b72= T79c0ff6
Te6edf3KEEPALIVE_MAX_RTT Tff7b72= T79c0ff1.75
Te6edf3KEEPALIVE_TIMEOUT_FACTOR Tff7b72= T79c0ff4
T8b949e"""
RTT timeout factor used in link timeout calculation.
"""
Te6edf3STALE_GRACE Tff7b72= T79c0ff5
T8b949e"""
Grace period in seconds used in link timeout calculation.
"""
Te6edf3KEEPALIVE_MAX Tff7b72= T79c0ff360
Te6edf3KEEPALIVE_MIN Tff7b72= T79c0ff5
Te6edf3KEEPALIVE Tff7b72= Te6edf3KEEPALIVE_MAX
T8b949e"""
Default interval for sending keep-alive packets on established links in seconds.
"""
Te6edf3STALE_FACTOR Tff7b72= T79c0ff2
Te6edf3STALE_TIME Tff7b72= Te6edf3STALE_FACTORTff7b72*Te6edf3KEEPALIVE
T8b949e"""
If no traffic or keep-alive packets are received within this period, the
link will be marked as stale, and a final keep-alive packet will be sent.
If after this no traffic or keep-alive packets are received within ``RTT`` *
``KEEPALIVE_TIMEOUT_FACTOR`` + ``STALE_GRACE``, the link is considered timed out,
and will be torn down.
"""

Te6edf3WATCHDOG_MAX_SLEEP Tff7b72= T79c0ff5

Te6edf3PENDING Tff7b72= T79c0ff0x00
Te6edf3HANDSHAKE Tff7b72= T79c0ff0x01
Te6edf3ACTIVE Tff7b72= T79c0ff0x02
Te6edf3STALE Tff7b72= T79c0ff0x03
Te6edf3CLOSED Tff7b72= T79c0ff0x04

Te6edf3TIMEOUT Tff7b72= T79c0ff0x01
Te6edf3INITIATOR_CLOSED Tff7b72= T79c0ff0x02
Te6edf3DESTINATION_CLOSED Tff7b72= T79c0ff0x03

Te6edf3ACCEPT_NONE Tff7b72= T79c0ff0x00
Te6edf3ACCEPT_APP Tff7b72= T79c0ff0x01
Te6edf3ACCEPT_ALL Tff7b72= T79c0ff0x02
Te6edf3resource_strategies Tff7b72= Tb4b4b4[Te6edf3ACCEPT_NONETb4b4b4, Te6edf3ACCEPT_APPTb4b4b4, Te6edf3ACCEPT_ALLTb4b4b4]

Te6edf3MODE_AES128_CBC Tff7b72= T79c0ff0x00
Te6edf3MODE_AES256_CBC Tff7b72= T79c0ff0x01
Te6edf3MODE_AES256_GCM Tff7b72= T79c0ff0x02
Te6edf3MODE_OTP_RESERVED Tff7b72= T79c0ff0x03
Te6edf3MODE_PQ_RESERVED_1 Tff7b72= T79c0ff0x04
Te6edf3MODE_PQ_RESERVED_2 Tff7b72= T79c0ff0x05
Te6edf3MODE_PQ_RESERVED_3 Tff7b72= T79c0ff0x06
Te6edf3MODE_PQ_RESERVED_4 Tff7b72= T79c0ff0x07
Te6edf3ENABLED_MODES Tff7b72= Tb4b4b4[Te6edf3MODE_AES256_CBCTb4b4b4]
Te6edf3MODE_DEFAULT Tff7b72= Te6edf3MODE_AES256_CBC
Te6edf3MODE_DESCRIPTIONS Tff7b72= Tb4b4b4{Te6edf3MODE_AES128_CBCTb4b4b4: Ta5d6ff"Ta5d6ffAES_128_CBCTa5d6ff"Tb4b4b4,
Te6edf3MODE_AES256_CBCTb4b4b4: Ta5d6ff"Ta5d6ffAES_256_CBCTa5d6ff"Tb4b4b4,
Te6edf3MODE_AES256_GCMTb4b4b4: Ta5d6ff"Ta5d6ffMODE_AES256_GCMTa5d6ff"Tb4b4b4,
Te6edf3MODE_OTP_RESERVEDTb4b4b4: Ta5d6ff"Ta5d6ffMODE_OTP_RESERVEDTa5d6ff"Tb4b4b4,
Te6edf3MODE_PQ_RESERVED_1Tb4b4b4: Ta5d6ff"Ta5d6ffMODE_PQ_RESERVED_1Ta5d6ff"Tb4b4b4,
Te6edf3MODE_PQ_RESERVED_2Tb4b4b4: Ta5d6ff"Ta5d6ffMODE_PQ_RESERVED_2Ta5d6ff"Tb4b4b4,
Te6edf3MODE_PQ_RESERVED_3Tb4b4b4: Ta5d6ff"Ta5d6ffMODE_PQ_RESERVED_3Ta5d6ff"Tb4b4b4,
Te6edf3MODE_PQ_RESERVED_4Tb4b4b4: Ta5d6ff"Ta5d6ffMODE_PQ_RESERVED_4Ta5d6ff"Tb4b4b4}

Te6edf3MTU_BYTEMASK Tff7b72= T79c0ff0x1FFFFF
Te6edf3MODE_BYTEMASK Tff7b72= T79c0ff0xE0

Tf0883e@staticmethod
Tff7b72def Td2a8ffsignalling_bytesTb4b4b4(Te6edf3mtuTb4b4b4, Te6edf3modeTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3mode Tff7b72in Te6edf3LinkTff7b72.Td2a8ffENABLED_MODESTb4b4b4: Tff7b72raise Tf85149TypeErrorTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffRequested link mode Tffd700{Te6edf3LinkTff7b72.Td2a8ffMODE_DESCRIPTIONSTb4b4b4[Te6edf3modeTb4b4b4]Tffd700}Ta5d6ff not enabledTa5d6ff"Tb4b4b4)
Te6edf3signalling_value Tff7b72= Tb4b4b4(Te6edf3mtu Tff7b72& Te6edf3LinkTff7b72.Td2a8ffMTU_BYTEMASKTb4b4b4)Tff7b72+Tb4b4b4(Tb4b4b4(Tb4b4b4(Te6edf3modeTff7b72<<T79c0ff5Tb4b4b4) Tff7b72& Te6edf3LinkTff7b72.Td2a8ffMODE_BYTEMASKTb4b4b4)Tff7b72<<T79c0ff16Tb4b4b4)
Tff7b72return Te6edf3structTff7b72.Td2a8ffpackTb4b4b4(Ta5d6ff"Ta5d6ff>ITa5d6ff"Tb4b4b4, Te6edf3signalling_valueTb4b4b4)Tb4b4b4[T79c0ff1Tb4b4b4:Tb4b4b4]

Tf0883e@staticmethod
Tff7b72def Td2a8ffmtu_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657lenTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4) Tff7b72== Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETff7b72+Te6edf3LinkTff7b72.Td2a8ffLINK_MTU_SIZETb4b4b4:
Tff7b72return Tb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4[Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETb4b4b4] Tff7b72<< T79c0ff16Tb4b4b4) Tff7b72+ Tb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4[Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETff7b72+T79c0ff1Tb4b4b4] Tff7b72<< T79c0ff8Tb4b4b4) Tff7b72+ Tb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4[Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETff7b72+T79c0ff2Tb4b4b4]Tb4b4b4) Tff7b72& Te6edf3LinkTff7b72.Td2a8ffMTU_BYTEMASK
Tff7b72elseTb4b4b4: Tff7b72return Tff7b72None

Tf0883e@staticmethod
Tff7b72def Td2a8ffmtu_from_lp_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657lenTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4) Tff7b72== Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffSIGLENGTHTff7b72/Tff7b72/T79c0ff8Tff7b72+Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETff7b72/Tff7b72/T79c0ff2Tff7b72+Te6edf3LinkTff7b72.Td2a8ffLINK_MTU_SIZETb4b4b4:
Te6edf3mtu_bytes Tff7b72= Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4[Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffSIGLENGTHTff7b72/Tff7b72/T79c0ff8Tff7b72+Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETff7b72/Tff7b72/T79c0ff2Tb4b4b4:Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffSIGLENGTHTff7b72/Tff7b72/T79c0ff8Tff7b72+Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETff7b72/Tff7b72/T79c0ff2Tff7b72+Te6edf3LinkTff7b72.Td2a8ffLINK_MTU_SIZETb4b4b4]
Tff7b72return Tb4b4b4(Te6edf3mtu_bytesTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72<< T79c0ff16Tb4b4b4) Tff7b72+ Tb4b4b4(Te6edf3mtu_bytesTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72<< T79c0ff8Tb4b4b4) Tff7b72+ Tb4b4b4(Te6edf3mtu_bytesTb4b4b4[T79c0ff2Tb4b4b4]Tb4b4b4) Tff7b72& Te6edf3LinkTff7b72.Td2a8ffMTU_BYTEMASK
Tff7b72elseTb4b4b4: Tff7b72return Tff7b72None

Tf0883e@staticmethod
Tff7b72def Td2a8ffmode_byteTb4b4b4(Te6edf3modeTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3mode Tff7b72in Te6edf3LinkTff7b72.Td2a8ffENABLED_MODESTb4b4b4: Tff7b72return Tb4b4b4(Te6edf3mode Tff7b72<< T79c0ff5Tb4b4b4) Tff7b72& Te6edf3LinkTff7b72.Td2a8ffMODE_BYTEMASK
Tff7b72elseTb4b4b4: Tff7b72raise Tf85149TypeErrorTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffRequested link mode Tffd700{Te6edf3modeTffd700}Ta5d6ff not enabledTa5d6ff"Tb4b4b4)

Tf0883e@staticmethod
Tff7b72def Td2a8ffmode_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657lenTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4) Tff7b72> Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETb4b4b4:
Te6edf3mode Tff7b72= Tb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4[Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETb4b4b4] Tff7b72& Te6edf3LinkTff7b72.Td2a8ffMODE_BYTEMASKTb4b4b4) Tff7b72>> T79c0ff5
Tff7b72return Te6edf3mode
Tff7b72elseTb4b4b4: Tff7b72return Te6edf3LinkTff7b72.Td2a8ffMODE_DEFAULT

Tf0883e@staticmethod
Tff7b72def Td2a8ffmode_from_lp_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657lenTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4) Tff7b72> Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffSIGLENGTHTff7b72/Tff7b72/T79c0ff8Tff7b72+Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETff7b72/Tff7b72/T79c0ff2Tb4b4b4:
Te6edf3mode Tff7b72= Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4[Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffSIGLENGTHTff7b72/Tff7b72/T79c0ff8Tff7b72+Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETff7b72/Tff7b72/T79c0ff2Tb4b4b4] Tff7b72>> T79c0ff5
Tff7b72return Te6edf3mode
Tff7b72elseTb4b4b4: Tff7b72return Te6edf3LinkTff7b72.Td2a8ffMODE_DEFAULT

Tf0883e@staticmethod
Tff7b72def Td2a8ffvalidate_requestTb4b4b4(Te6edf3ownerTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3packetTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4) Tff7b72== Te6edf3LinkTff7b72.Td2a8ffECPUBSIZE Tff7b72or Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4) Tff7b72== Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETff7b72+Te6edf3LinkTff7b72.Td2a8ffLINK_MTU_SIZETb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3link Tff7b72= Te6edf3LinkTb4b4b4(Te6edf3owner Tff7b72= Te6edf3ownerTb4b4b4, Te6edf3peer_pub_bytesTff7b72=Te6edf3dataTb4b4b4[Tb4b4b4:Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETff7b72/Tff7b72/T79c0ff2Tb4b4b4]Tb4b4b4, Te6edf3peer_sig_pub_bytesTff7b72=Te6edf3dataTb4b4b4[Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETff7b72/Tff7b72/T79c0ff2Tb4b4b4:Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETb4b4b4]Tb4b4b4)
Te6edf3linkTff7b72.Td2a8ffset_link_idTb4b4b4(Te6edf3packetTb4b4b4)

Tff7b72if Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4) Tff7b72== Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETff7b72+Te6edf3LinkTff7b72.Td2a8ffLINK_MTU_SIZETb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffLink request includes MTU signallingTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4) T8b949e# TODO: Remove debug
Tff7b72tryTb4b4b4:
Te6edf3linkTff7b72.Td2a8ffmtu Tff7b72= Te6edf3LinkTff7b72.Td2a8ffmtu_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4) Tff7b72or Te6edf3ReticulumTff7b72.Td2a8ffMTU
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fftrace_exceptionTb4b4b4(Te6edf3eTb4b4b4)
Te6edf3linkTff7b72.Td2a8ffmtu Tff7b72= Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffMTU

Te6edf3linkTff7b72.Td2a8ffmode Tff7b72= Te6edf3LinkTff7b72.Td2a8ffmode_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)
T8b949e# TODO: Remove debug
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffIncoming link request with mode Tffd700{Te6edf3LinkTff7b72.Td2a8ffMODE_DESCRIPTIONSTb4b4b4[Te6edf3linkTff7b72.Td2a8ffmodeTb4b4b4]Tffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)

Te6edf3linkTff7b72.Td2a8ffupdate_mduTb4b4b4(Tb4b4b4)
Te6edf3linkTff7b72.Td2a8ffdestination Tff7b72= Te6edf3packetTff7b72.Td2a8ffdestination
Te6edf3linkTff7b72.Td2a8ffestablishment_timeout Tff7b72= Te6edf3LinkTff7b72.Td2a8ffESTABLISHMENT_TIMEOUT_PER_HOP Tff7b72* Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3packetTff7b72.Td2a8ffhopsTb4b4b4) Tff7b72+ Te6edf3LinkTff7b72.Td2a8ffKEEPALIVE
Te6edf3linkTff7b72.Td2a8ffestablishment_cost Tff7b72+Tff7b72= Tffa657lenTb4b4b4(Te6edf3packetTff7b72.Td2a8ffrawTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffValidating link request Tffd700{Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3linkTff7b72.Td2a8fflink_idTb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffLink MTU configured to Tffd700{Te6edf3RNSTff7b72.Td2a8ffprettysizeTb4b4b4(Te6edf3linkTff7b72.Td2a8ffmtuTb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffEstablishment timeout is Tffd700{Te6edf3RNSTff7b72.Td2a8ffprettytimeTb4b4b4(Te6edf3linkTff7b72.Td2a8ffestablishment_timeoutTb4b4b4)Tffd700}Ta5d6ff for incoming link request Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3linkTff7b72.Td2a8fflink_idTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4)
Te6edf3linkTff7b72.Td2a8ffhandshakeTb4b4b4(Tb4b4b4)
Te6edf3linkTff7b72.Td2a8ffattached_interface Tff7b72= Te6edf3packetTff7b72.Td2a8ffreceiving_interface
Te6edf3linkTff7b72.Td2a8ffproveTb4b4b4(Tb4b4b4)
Te6edf3linkTff7b72.Td2a8ffrequest_time Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffregister_linkTb4b4b4(Te6edf3linkTb4b4b4)
Te6edf3linkTff7b72.Td2a8fflast_inbound Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Te6edf3linkTff7b72.Td2a8ff__update_phy_statsTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3force_updateTff7b72=Tff7b72TrueTb4b4b4)
Te6edf3linkTff7b72.Td2a8ffstart_watchdogTb4b4b4(Tb4b4b4)

Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffIncoming link request Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3linkTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff accepted on Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3linkTff7b72.Td2a8ffattached_interfaceTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72return Te6edf3link

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffValidating link request failed: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Tff7b72return Tff7b72None

Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffInvalid link request payload size of Tffd700{Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4)Tffd700}Ta5d6ff bytes, dropping requestTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72return Tff7b72None


Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3destinationTff7b72=Tff7b72NoneTb4b4b4, Te6edf3established_callbackTff7b72=Tff7b72NoneTb4b4b4, Te6edf3closed_callbackTff7b72=Tff7b72NoneTb4b4b4, Te6edf3ownerTff7b72=Tff7b72NoneTb4b4b4, Te6edf3peer_pub_bytesTff7b72=Tff7b72NoneTb4b4b4, Te6edf3peer_sig_pub_bytesTff7b72=Tff7b72NoneTb4b4b4, Te6edf3modeTff7b72=Te6edf3MODE_DEFAULTTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3destination Tff7b72!= Tff7b72None Tff7b72and Te6edf3destinationTff7b72.Td2a8fftype Tff7b72!= Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffSINGLETb4b4b4: Tff7b72raise Tf85149TypeErrorTb4b4b4(Ta5d6ff"Ta5d6ffLinks can only be established to the Tffea00\"Ta5d6ffsingleTffea00\"Ta5d6ff destination typeTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmode Tff7b72= Te6edf3mode
Tff7b72selfTff7b72.Td2a8ffrtt Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffmtu Tff7b72= Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffMTU
Tff7b72selfTff7b72.Td2a8ffestablishment_cost Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ffestablishment_rate Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffexpected_rate Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffcallbacks Tff7b72= Te6edf3LinkCallbacksTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffresource_strategy Tff7b72= Te6edf3LinkTff7b72.Td2a8ffACCEPT_NONE
Tff7b72selfTff7b72.Td2a8fflast_resource_window Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8fflast_resource_eifr Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffoutgoing_resources Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffincoming_resources Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffpending_requests Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8fflast_inbound Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8fflast_outbound Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8fflast_keepalive Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8fflast_proof Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8fflast_data Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8fftx Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ffrx Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8fftxbytes Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ffrxbytes Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ffrssi Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffsnr Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffq Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8fftraffic_timeout_factor Tff7b72= Te6edf3LinkTff7b72.Td2a8ffTRAFFIC_TIMEOUT_FACTOR
Tff7b72selfTff7b72.Td2a8ffkeepalive_timeout_factor Tff7b72= Te6edf3LinkTff7b72.Td2a8ffKEEPALIVE_TIMEOUT_FACTOR
Tff7b72selfTff7b72.Td2a8ffkeepalive Tff7b72= Te6edf3LinkTff7b72.Td2a8ffKEEPALIVE
Tff7b72selfTff7b72.Td2a8ffstale_time Tff7b72= Te6edf3LinkTff7b72.Td2a8ffSTALE_TIME
Tff7b72selfTff7b72.Td2a8ffwatchdog_lock Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3LinkTff7b72.Td2a8ffPENDING
Tff7b72selfTff7b72.Td2a8ffactivated_at Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8fftype Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffLINK
Tff7b72selfTff7b72.Td2a8ffowner Tff7b72= Te6edf3owner
Tff7b72selfTff7b72.Td2a8ffdestination Tff7b72= Te6edf3destination
Tff7b72selfTff7b72.Td2a8ffexpected_hops Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffattached_interface Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff__remote_identity Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff__track_phy_stats Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_channel Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffdestination Tff7b72== Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffinitiator Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffprv Tff7b72= Te6edf3X25519PrivateKeyTff7b72.Td2a8ffgenerateTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffsig_prv Tff7b72= Tff7b72selfTff7b72.Td2a8ffownerTff7b72.Td2a8ffidentityTff7b72.Td2a8ffsig_prv
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffinitiator Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffexpected_hops Tff7b72= Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhops_toTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffhashTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffestablishment_timeout Tff7b72= Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffget_instanceTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffget_first_hop_timeoutTb4b4b4(Te6edf3destinationTff7b72.Td2a8ffhashTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffestablishment_timeout Tff7b72+Tff7b72= Te6edf3LinkTff7b72.Td2a8ffESTABLISHMENT_TIMEOUT_PER_HOP Tff7b72* Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhops_toTb4b4b4(Te6edf3destinationTff7b72.Td2a8ffhashTb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffprv Tff7b72= Te6edf3X25519PrivateKeyTff7b72.Td2a8ffgenerateTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffsig_prv Tff7b72= Te6edf3Ed25519PrivateKeyTff7b72.Td2a8ffgenerateTb4b4b4(Tb4b4b4)

Tff7b72selfTff7b72.Td2a8fftoken Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffpub Tff7b72= Tff7b72selfTff7b72.Td2a8ffprvTff7b72.Td2a8ffpublic_keyTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpub_bytes Tff7b72= Tff7b72selfTff7b72.Td2a8ffpubTff7b72.Td2a8ffpublic_bytesTb4b4b4(Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffsig_pub Tff7b72= Tff7b72selfTff7b72.Td2a8ffsig_prvTff7b72.Td2a8ffpublic_keyTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffsig_pub_bytes Tff7b72= Tff7b72selfTff7b72.Td2a8ffsig_pubTff7b72.Td2a8ffpublic_bytesTb4b4b4(Tb4b4b4)

Tff7b72if Te6edf3peer_pub_bytes Tff7b72== Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpeer_pub Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffpeer_pub_bytes Tff7b72= Tff7b72None
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffload_peerTb4b4b4(Te6edf3peer_pub_bytesTb4b4b4, Te6edf3peer_sig_pub_bytesTb4b4b4)

Tff7b72if Te6edf3established_callback Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffset_link_established_callbackTb4b4b4(Te6edf3established_callbackTb4b4b4)

Tff7b72if Te6edf3closed_callback Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffset_link_closed_callbackTb4b4b4(Te6edf3closed_callbackTb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffinitiatorTb4b4b4:
Te6edf3signalling_bytes Tff7b72= Ta5d6ffbTa5d6ff"Ta5d6ff"
Te6edf3nh_hw_mtu Tff7b72= Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffnext_hop_interface_hw_mtuTb4b4b4(Te6edf3destinationTff7b72.Td2a8ffhashTb4b4b4)
Tff7b72if Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8fflink_mtu_discoveryTb4b4b4(Tb4b4b4) Tff7b72and Te6edf3nh_hw_mtuTb4b4b4:
Te6edf3signalling_bytes Tff7b72= Te6edf3LinkTff7b72.Td2a8ffsignalling_bytesTb4b4b4(Te6edf3nh_hw_mtuTb4b4b4, Tff7b72selfTff7b72.Td2a8ffmodeTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffSignalling link MTU of Tffd700{Te6edf3RNSTff7b72.Td2a8ffprettysizeTb4b4b4(Te6edf3nh_hw_mtuTb4b4b4)Tffd700}Ta5d6ff for linkTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4) T8b949e# TODO: Remove debug
Tff7b72elseTb4b4b4: Te6edf3signalling_bytes Tff7b72= Te6edf3LinkTff7b72.Td2a8ffsignalling_bytesTb4b4b4(Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffMTUTb4b4b4, Tff7b72selfTff7b72.Td2a8ffmodeTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffEstablishing link with mode Tffd700{Te6edf3LinkTff7b72.Td2a8ffMODE_DESCRIPTIONSTb4b4b4[Tff7b72selfTff7b72.Td2a8ffmodeTb4b4b4]Tffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4) T8b949e# TODO: Remove debug
Tff7b72selfTff7b72.Td2a8ffrequest_data Tff7b72= Tff7b72selfTff7b72.Td2a8ffpub_bytesTff7b72+Tff7b72selfTff7b72.Td2a8ffsig_pub_bytesTff7b72+Te6edf3signalling_bytes
Tff7b72selfTff7b72.Td2a8ffpacket Tff7b72= Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4(Te6edf3destinationTb4b4b4, Tff7b72selfTff7b72.Td2a8ffrequest_dataTb4b4b4, Te6edf3packet_typeTff7b72=Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffLINKREQUESTTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpacketTff7b72.Td2a8ffpackTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffestablishment_cost Tff7b72+Tff7b72= Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ffpacketTff7b72.Td2a8ffrawTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffset_link_idTb4b4b4(Tff7b72selfTff7b72.Td2a8ffpacketTb4b4b4)
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffregister_linkTb4b4b4(Tff7b72selfTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrequest_time Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffstart_watchdogTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpacketTff7b72.Td2a8ffsendTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffhad_outboundTb4b4b4(Tb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffLink request Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Tff7b72selfTff7b72.Td2a8fflink_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff sent to Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdestinationTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffEstablishment timeout is Tffd700{Te6edf3RNSTff7b72.Td2a8ffprettytimeTb4b4b4(Tff7b72selfTff7b72.Td2a8ffestablishment_timeoutTb4b4b4)Tffd700}Ta5d6ff for link request Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Tff7b72selfTff7b72.Td2a8fflink_idTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4)


Tff7b72def Td2a8ffload_peerTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3peer_pub_bytesTb4b4b4, Te6edf3peer_sig_pub_bytesTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpeer_pub_bytes Tff7b72= Te6edf3peer_pub_bytes
Tff7b72selfTff7b72.Td2a8ffpeer_pub Tff7b72= Te6edf3X25519PublicKeyTff7b72.Td2a8fffrom_public_bytesTb4b4b4(Tff7b72selfTff7b72.Td2a8ffpeer_pub_bytesTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffpeer_sig_pub_bytes Tff7b72= Te6edf3peer_sig_pub_bytes
Tff7b72selfTff7b72.Td2a8ffpeer_sig_pub Tff7b72= Te6edf3Ed25519PublicKeyTff7b72.Td2a8fffrom_public_bytesTb4b4b4(Tff7b72selfTff7b72.Td2a8ffpeer_sig_pub_bytesTb4b4b4)

Tff7b72if Tff7b72not Tffa657hasattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffpeer_pubTb4b4b4, Ta5d6ff"Ta5d6ffcurveTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpeer_pubTff7b72.Td2a8ffcurve Tff7b72= Te6edf3LinkTff7b72.Td2a8ffCURVE

Tf0883e@staticmethod
Tff7b72def Td2a8fflink_id_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4:
Te6edf3hashable_part Tff7b72= Te6edf3packetTff7b72.Td2a8ffget_hashable_partTb4b4b4(Tb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4) Tff7b72> Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETb4b4b4:
Te6edf3diff Tff7b72= Tffa657lenTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4) Tff7b72- Te6edf3LinkTff7b72.Td2a8ffECPUBSIZE
Te6edf3hashable_part Tff7b72= Te6edf3hashable_partTb4b4b4[Tb4b4b4:Tff7b72-Te6edf3diffTb4b4b4]

Tff7b72return Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fftruncated_hashTb4b4b4(Te6edf3hashable_partTb4b4b4)

Tff7b72def Td2a8ffset_link_idTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8fflink_id Tff7b72= Te6edf3LinkTff7b72.Td2a8fflink_id_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffhash Tff7b72= Tff7b72selfTff7b72.Td2a8fflink_id

Tff7b72def Td2a8ffhandshakeTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3LinkTff7b72.Td2a8ffPENDING Tff7b72and Tff7b72selfTff7b72.Td2a8ffprv Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3LinkTff7b72.Td2a8ffHANDSHAKE
Tff7b72selfTff7b72.Td2a8ffshared_key Tff7b72= Tff7b72selfTff7b72.Td2a8ffprvTff7b72.Td2a8ffexchangeTb4b4b4(Tff7b72selfTff7b72.Td2a8ffpeer_pubTb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffmode Tff7b72== Te6edf3LinkTff7b72.Td2a8ffMODE_AES128_CBCTb4b4b4: Te6edf3derived_key_length Tff7b72= T79c0ff32
Tff7b72elif Tff7b72selfTff7b72.Td2a8ffmode Tff7b72== Te6edf3LinkTff7b72.Td2a8ffMODE_AES256_CBCTb4b4b4: Te6edf3derived_key_length Tff7b72= T79c0ff64
Tff7b72elseTb4b4b4: Tff7b72raise Tf85149TypeErrorTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffInvalid link mode Tffd700{Tff7b72selfTff7b72.Td2a8ffmodeTffd700}Ta5d6ff on Tffd700{Tff7b72selfTffd700}Ta5d6ff"Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffderived_key Tff7b72= Te6edf3RNSTff7b72.Td2a8ffCryptographyTff7b72.Td2a8ffhkdfTb4b4b4(
Te6edf3lengthTff7b72=Te6edf3derived_key_lengthTb4b4b4,
Te6edf3derive_fromTff7b72=Tff7b72selfTff7b72.Td2a8ffshared_keyTb4b4b4,
Te6edf3saltTff7b72=Tff7b72selfTff7b72.Td2a8ffget_saltTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3contextTff7b72=Tff7b72selfTff7b72.Td2a8ffget_contextTb4b4b4(Tb4b4b4)Tb4b4b4)

Tff7b72elseTb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffHandshake attempt on Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff with invalid state Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstatusTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)


Tff7b72def Td2a8ffproveTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3signalling_bytes Tff7b72= Te6edf3LinkTff7b72.Td2a8ffsignalling_bytesTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmtuTb4b4b4, Tff7b72selfTff7b72.Td2a8ffmodeTb4b4b4)
Te6edf3signed_data Tff7b72= Tff7b72selfTff7b72.Td2a8fflink_idTff7b72+Tff7b72selfTff7b72.Td2a8ffpub_bytesTff7b72+Tff7b72selfTff7b72.Td2a8ffsig_pub_bytesTff7b72+Te6edf3signalling_bytes
Te6edf3signature Tff7b72= Tff7b72selfTff7b72.Td2a8ffownerTff7b72.Td2a8ffidentityTff7b72.Td2a8ffsignTb4b4b4(Te6edf3signed_dataTb4b4b4)

Te6edf3proof_data Tff7b72= Te6edf3signatureTff7b72+Tff7b72selfTff7b72.Td2a8ffpub_bytesTff7b72+Te6edf3signalling_bytes
Te6edf3proof Tff7b72= Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3proof_dataTb4b4b4, Te6edf3packet_typeTff7b72=Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffPROOFTb4b4b4, Te6edf3contextTff7b72=Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffLRPROOFTb4b4b4)
Te6edf3proofTff7b72.Td2a8ffsendTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffestablishment_cost Tff7b72+Tff7b72= Tffa657lenTb4b4b4(Te6edf3proofTff7b72.Td2a8ffrawTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffhad_outboundTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8ffprove_packetTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4)Tb4b4b4:
Te6edf3signature Tff7b72= Tff7b72selfTff7b72.Td2a8ffsignTb4b4b4(Te6edf3packetTff7b72.Td2a8ffpacket_hashTb4b4b4)
T8b949e# TODO: Hardcoded as explicit proof for now
T8b949e# if RNS.Reticulum.should_use_implicit_proof():
T8b949e# proof_data = signature
T8b949e# else:
T8b949e# proof_data = packet.packet_hash + signature
Te6edf3proof_data Tff7b72= Te6edf3packetTff7b72.Td2a8ffpacket_hash Tff7b72+ Te6edf3signature

Te6edf3proof Tff7b72= Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3proof_dataTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffPROOFTb4b4b4)
Te6edf3proofTff7b72.Td2a8ffsendTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffhad_outboundTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffvalidate_proofTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3LinkTff7b72.Td2a8ffPENDINGTb4b4b4:
Te6edf3signalling_bytes Tff7b72= Ta5d6ffbTa5d6ff"Ta5d6ff"
Te6edf3confirmed_mtu Tff7b72= Tff7b72None
Te6edf3mode Tff7b72= Te6edf3LinkTff7b72.Td2a8ffmode_from_lp_packetTb4b4b4(Te6edf3packetTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffValidating link request proof with mode Tffd700{Te6edf3LinkTff7b72.Td2a8ffMODE_DESCRIPTIONSTb4b4b4[Te6edf3modeTb4b4b4]Tffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4) T8b949e# TODO: Remove debug
Tff7b72if Te6edf3mode Tff7b72!= Tff7b72selfTff7b72.Td2a8ffmodeTb4b4b4: Tff7b72raise Tf85149TypeErrorTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffInvalid link mode Tffd700{Te6edf3modeTffd700}Ta5d6ff in link request proofTa5d6ff"Tb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4) Tff7b72== Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffSIGLENGTHTff7b72/Tff7b72/T79c0ff8Tff7b72+Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETff7b72/Tff7b72/T79c0ff2Tff7b72+Te6edf3LinkTff7b72.Td2a8ffLINK_MTU_SIZETb4b4b4:
Te6edf3confirmed_mtu Tff7b72= Te6edf3LinkTff7b72.Td2a8ffmtu_from_lp_packetTb4b4b4(Te6edf3packetTb4b4b4)
Te6edf3signalling_bytes Tff7b72= Te6edf3LinkTff7b72.Td2a8ffsignalling_bytesTb4b4b4(Te6edf3confirmed_mtuTb4b4b4, Te6edf3modeTb4b4b4)
Te6edf3packetTff7b72.Td2a8ffdata Tff7b72= Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4[Tb4b4b4:Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffSIGLENGTHTff7b72/Tff7b72/T79c0ff8Tff7b72+Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETff7b72/Tff7b72/T79c0ff2Tb4b4b4]
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffDestination confirmed link MTU of Tffd700{Te6edf3RNSTff7b72.Td2a8ffprettysizeTb4b4b4(Te6edf3confirmed_mtuTb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4) T8b949e# TODO: Remove debug

Tff7b72if Tff7b72selfTff7b72.Td2a8ffinitiator Tff7b72and Tffa657lenTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4) Tff7b72== Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffSIGLENGTHTff7b72/Tff7b72/T79c0ff8Tff7b72+Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETff7b72/Tff7b72/T79c0ff2Tb4b4b4:
Te6edf3peer_pub_bytes Tff7b72= Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4[Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffSIGLENGTHTff7b72/Tff7b72/T79c0ff8Tb4b4b4:Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffSIGLENGTHTff7b72/Tff7b72/T79c0ff8Tff7b72+Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETff7b72/Tff7b72/T79c0ff2Tb4b4b4]
Te6edf3peer_sig_pub_bytes Tff7b72= Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffidentityTff7b72.Td2a8ffget_public_keyTb4b4b4(Tb4b4b4)Tb4b4b4[Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETff7b72/Tff7b72/T79c0ff2Tb4b4b4:Te6edf3LinkTff7b72.Td2a8ffECPUBSIZETb4b4b4]
Tff7b72selfTff7b72.Td2a8ffload_peerTb4b4b4(Te6edf3peer_pub_bytesTb4b4b4, Te6edf3peer_sig_pub_bytesTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffhandshakeTb4b4b4(Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffestablishment_cost Tff7b72+Tff7b72= Tffa657lenTb4b4b4(Te6edf3packetTff7b72.Td2a8ffrawTb4b4b4)
Te6edf3signed_data Tff7b72= Tff7b72selfTff7b72.Td2a8fflink_idTff7b72+Tff7b72selfTff7b72.Td2a8ffpeer_pub_bytesTff7b72+Tff7b72selfTff7b72.Td2a8ffpeer_sig_pub_bytesTff7b72+Te6edf3signalling_bytes
Te6edf3signature Tff7b72= Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4[Tb4b4b4:Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffSIGLENGTHTff7b72/Tff7b72/T79c0ff8Tb4b4b4]
Tff7b72if Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffidentityTff7b72.Td2a8ffvalidateTb4b4b4(Te6edf3signatureTb4b4b4, Te6edf3signed_dataTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72!= Te6edf3LinkTff7b72.Td2a8ffHANDSHAKETb4b4b4:
Tff7b72raise Tf85149IOErrorTb4b4b4(Ta5d6ff"Ta5d6ffInvalid link state for proof validation: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstatusTb4b4b4)Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffrtt Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72- Tff7b72selfTff7b72.Td2a8ffrequest_time
Tff7b72selfTff7b72.Td2a8ffattached_interface Tff7b72= Te6edf3packetTff7b72.Td2a8ffreceiving_interface
Tff7b72selfTff7b72.Td2a8ff__remote_identity Tff7b72= Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffidentity
Tff7b72selfTff7b72.Td2a8ffmtu Tff7b72= Te6edf3confirmed_mtu Tff7b72or Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffMTU
Tff7b72selfTff7b72.Td2a8ffupdate_mduTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3LinkTff7b72.Td2a8ffACTIVE
Tff7b72selfTff7b72.Td2a8ffactivated_at Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflast_proof Tff7b72= Tff7b72selfTff7b72.Td2a8ffactivated_at
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffactivate_linkTb4b4b4(Tff7b72selfTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffLink Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff established with Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdestinationTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff, RTT is Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyshorttimeTb4b4b4(Tff7b72selfTff7b72.Td2a8ffrttTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffrtt Tff7b72!= Tff7b72None Tff7b72and Tff7b72selfTff7b72.Td2a8ffestablishment_cost Tff7b72!= Tff7b72None Tff7b72and Tff7b72selfTff7b72.Td2a8ffrtt Tff7b72> T79c0ff0 Tff7b72and Tff7b72selfTff7b72.Td2a8ffestablishment_cost Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffestablishment_rate Tff7b72= Tff7b72selfTff7b72.Td2a8ffestablishment_costTff7b72/Tff7b72selfTff7b72.Td2a8ffrtt

Tff7b72selfTff7b72.Td2a8ff__update_keepaliveTb4b4b4(Tb4b4b4)

Te6edf3rtt_data Tff7b72= Te6edf3umsgpackTff7b72.Td2a8ffpackbTb4b4b4(Tff7b72selfTff7b72.Td2a8ffrttTb4b4b4)
Te6edf3rtt_packet Tff7b72= Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3rtt_dataTb4b4b4, Te6edf3contextTff7b72=Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffLRRTTTb4b4b4)
Te6edf3rtt_packetTff7b72.Td2a8ffsendTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffhad_outboundTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff__update_phy_statsTb4b4b4(Te6edf3packetTb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8fflink_established Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8fflink_establishedTb4b4b4, Te6edf3argsTff7b72=Tb4b4b4(Tff7b72selfTb4b4b4,Tb4b4b4)Tb4b4b4)
Te6edf3threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffInvalid link proof signature received by Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. Ignoring.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3LinkTff7b72.Td2a8ffCLOSED
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffAn error ocurred while validating link request proof on Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)


Tff7b72def Td2a8ffidentifyTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3identityTb4b4b4)Tb4b4b4:
T8b949e"""
Identifies the initiator of the link to the remote peer. This can only happen
once the link has been established, and is carried out over the encrypted link.
The identity is only revealed to the remote peer, and initiator anonymity is
thus preserved. This method can be used for authentication.

:param identity: An RNS.Identity instance to identify as.
"""
Tff7b72if Tff7b72selfTff7b72.Td2a8ffinitiator Tff7b72and Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3LinkTff7b72.Td2a8ffACTIVETb4b4b4:
Te6edf3signed_data Tff7b72= Tff7b72selfTff7b72.Td2a8fflink_id Tff7b72+ Te6edf3identityTff7b72.Td2a8ffget_public_keyTb4b4b4(Tb4b4b4)
Te6edf3signature Tff7b72= Te6edf3identityTff7b72.Td2a8ffsignTb4b4b4(Te6edf3signed_dataTb4b4b4)
Te6edf3proof_data Tff7b72= Te6edf3identityTff7b72.Td2a8ffget_public_keyTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3signature

Te6edf3proof Tff7b72= Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3proof_dataTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffDATATb4b4b4, Te6edf3context Tff7b72= Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffLINKIDENTIFYTb4b4b4)
Te6edf3proofTff7b72.Td2a8ffsendTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffhad_outboundTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8ffrequestTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3pathTb4b4b4, Te6edf3data Tff7b72= Tff7b72NoneTb4b4b4, Te6edf3response_callback Tff7b72= Tff7b72NoneTb4b4b4, Te6edf3failed_callback Tff7b72= Tff7b72NoneTb4b4b4, Te6edf3progress_callback Tff7b72= Tff7b72NoneTb4b4b4, Te6edf3timeout Tff7b72= Tff7b72NoneTb4b4b4)Tb4b4b4:
T8b949e"""
Sends a request to the remote peer.

:param path: The request path.
:param response_callback: An optional function or method with the signature *response_callback(request_receipt)* to be called when a response is received. See the :ref:`Request Example<example-request>` for more info.
:param failed_callback: An optional function or method with the signature *failed_callback(request_receipt)* to be called when a request fails. See the :ref:`Request Example<example-request>` for more info.
:param progress_callback: An optional function or method with the signature *progress_callback(request_receipt)* to be called when progress is made receiving the response. Progress can be accessed as a float between 0.0 and 1.0 by the *request_receipt.progress* property.
:param timeout: An optional timeout in seconds for the request. If *None* is supplied it will be calculated based on link RTT.
:returns: A :ref:`RNS.RequestReceipt<api-requestreceipt>` instance if the request was sent, or *False* if it was not.
"""
Te6edf3request_path_hash Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fftruncated_hashTb4b4b4(Te6edf3pathTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3unpacked_request Tff7b72= Tb4b4b4[Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3request_path_hashTb4b4b4, Te6edf3dataTb4b4b4]
Te6edf3packed_request Tff7b72= Te6edf3umsgpackTff7b72.Td2a8ffpackbTb4b4b4(Te6edf3unpacked_requestTb4b4b4)

Tff7b72if Te6edf3timeout Tff7b72== Tff7b72NoneTb4b4b4:
Te6edf3timeout Tff7b72= Tff7b72selfTff7b72.Td2a8ffrtt Tff7b72* Tff7b72selfTff7b72.Td2a8fftraffic_timeout_factor Tff7b72+ Te6edf3RNSTff7b72.Td2a8ffResourceTff7b72.Td2a8ffRESPONSE_MAX_GRACE_TIMETff7b72*T79c0ff1.125

Tff7b72if Tffa657lenTb4b4b4(Te6edf3packed_requestTb4b4b4) Tff7b72<Tff7b72= Tff7b72selfTff7b72.Td2a8ffmduTb4b4b4:
Te6edf3request_packet Tff7b72= Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packed_requestTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffDATATb4b4b4, Te6edf3context Tff7b72= Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffREQUESTTb4b4b4)
Te6edf3packet_receipt Tff7b72= Te6edf3request_packetTff7b72.Td2a8ffsendTb4b4b4(Tb4b4b4)

Tff7b72if Te6edf3packet_receipt Tff7b72== Tff7b72FalseTb4b4b4:
Tff7b72return Tff7b72False
Tff7b72elseTb4b4b4:
Te6edf3packet_receiptTff7b72.Td2a8ffset_timeoutTb4b4b4(Te6edf3timeoutTb4b4b4)
Tff7b72return Te6edf3RequestReceiptTb4b4b4(
Tff7b72selfTb4b4b4,
Te6edf3packet_receipt Tff7b72= Te6edf3packet_receiptTb4b4b4,
Te6edf3response_callback Tff7b72= Te6edf3response_callbackTb4b4b4,
Te6edf3failed_callback Tff7b72= Te6edf3failed_callbackTb4b4b4,
Te6edf3progress_callback Tff7b72= Te6edf3progress_callbackTb4b4b4,
Te6edf3timeout Tff7b72= Te6edf3timeoutTb4b4b4,
Te6edf3request_size Tff7b72= Tffa657lenTb4b4b4(Te6edf3packed_requestTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3request_id Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fftruncated_hashTb4b4b4(Te6edf3packed_requestTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffSending request Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3request_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff as resource.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3request_resource Tff7b72= Te6edf3RNSTff7b72.Td2a8ffResourceTb4b4b4(Te6edf3packed_requestTb4b4b4, Tff7b72selfTb4b4b4, Te6edf3request_id Tff7b72= Te6edf3request_idTb4b4b4, Te6edf3is_response Tff7b72= Tff7b72FalseTb4b4b4, Te6edf3timeout Tff7b72= Te6edf3timeoutTb4b4b4)

Tff7b72return Te6edf3RequestReceiptTb4b4b4(
Tff7b72selfTb4b4b4,
Te6edf3resource Tff7b72= Te6edf3request_resourceTb4b4b4,
Te6edf3response_callback Tff7b72= Te6edf3response_callbackTb4b4b4,
Te6edf3failed_callback Tff7b72= Te6edf3failed_callbackTb4b4b4,
Te6edf3progress_callback Tff7b72= Te6edf3progress_callbackTb4b4b4,
Te6edf3timeout Tff7b72= Te6edf3timeoutTb4b4b4,
Te6edf3request_size Tff7b72= Tffa657lenTb4b4b4(Te6edf3packed_requestTb4b4b4)Tb4b4b4,
Tb4b4b4)


Tff7b72def Td2a8ffupdate_mduTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmdu Tff7b72= Tff7b72selfTff7b72.Td2a8ffmtu Tff7b72- Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffHEADER_MAXSIZE Tff7b72- Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffIFAC_MIN_SIZE
Tff7b72selfTff7b72.Td2a8ffmdu Tff7b72= Te6edf3mathTff7b72.Td2a8fffloorTb4b4b4(Tb4b4b4(Tff7b72selfTff7b72.Td2a8ffmtuTff7b72-Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffIFAC_MIN_SIZETff7b72-Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffHEADER_MINSIZETff7b72-Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffTOKEN_OVERHEADTb4b4b4)Tff7b72/Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffAES128_BLOCKSIZETb4b4b4)Tff7b72*Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffAES128_BLOCKSIZE Tff7b72- T79c0ff1

Tff7b72def Td2a8ffrtt_packetTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3measured_rtt Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72- Tff7b72selfTff7b72.Td2a8ffrequest_time
Te6edf3plaintext Tff7b72= Tff7b72selfTff7b72.Td2a8ffdecryptTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4)
Tff7b72if Te6edf3plaintext Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3rtt Tff7b72= Te6edf3umsgpackTff7b72.Td2a8ffunpackbTb4b4b4(Te6edf3plaintextTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrtt Tff7b72= Tffa657maxTb4b4b4(Te6edf3measured_rttTb4b4b4, Te6edf3rttTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3LinkTff7b72.Td2a8ffACTIVE
Tff7b72selfTff7b72.Td2a8ffactivated_at Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffrtt Tff7b72!= Tff7b72None Tff7b72and Tff7b72selfTff7b72.Td2a8ffestablishment_cost Tff7b72!= Tff7b72None Tff7b72and Tff7b72selfTff7b72.Td2a8ffrtt Tff7b72> T79c0ff0 Tff7b72and Tff7b72selfTff7b72.Td2a8ffestablishment_cost Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffestablishment_rate Tff7b72= Tff7b72selfTff7b72.Td2a8ffestablishment_costTff7b72/Tff7b72selfTff7b72.Td2a8ffrtt

Tff7b72selfTff7b72.Td2a8ff__update_keepaliveTb4b4b4(Tb4b4b4)

Tff7b72tryTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffownerTff7b72.Td2a8ffcallbacksTff7b72.Td2a8fflink_established Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffownerTff7b72.Td2a8ffcallbacksTff7b72.Td2a8fflink_establishedTb4b4b4(Tff7b72selfTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError occurred in external link establishment callback. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError occurred while processing RTT packet, tearing down link. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8fftrack_phy_statsTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3trackTb4b4b4)Tb4b4b4:
T8b949e"""
You can enable physical layer statistics on a per-link basis. If this is enabled,
and the link is running over an interface that supports reporting physical layer
statistics, you will be able to retrieve stats such as *RSSI*, *SNR* and physical
*Link Quality* for the link.

:param track: Whether or not to keep track of physical layer statistics. Value must be ``True`` or ``False``.
"""
Tff7b72if Te6edf3trackTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff__track_phy_stats Tff7b72= Tff7b72True
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff__track_phy_stats Tff7b72= Tff7b72False

Tff7b72def Td2a8ffget_rssiTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: The physical layer *Received Signal Strength Indication* if available, otherwise ``None``. Physical layer statistics must be enabled on the link for this method to return a value.
"""
Tff7b72if Tff7b72selfTff7b72.Td2a8ff__track_phy_statsTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffrssi
Tff7b72elseTb4b4b4:
Tff7b72return Tff7b72None

Tff7b72def Td2a8ffget_snrTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: The physical layer *Signal-to-Noise Ratio* if available, otherwise ``None``. Physical layer statistics must be enabled on the link for this method to return a value.
"""
Tff7b72if Tff7b72selfTff7b72.Td2a8ff__track_phy_statsTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffsnr
Tff7b72elseTb4b4b4:
Tff7b72return Tff7b72None

Tff7b72def Td2a8ffget_qTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: The physical layer *Link Quality* if available, otherwise ``None``. Physical layer statistics must be enabled on the link for this method to return a value.
"""
Tff7b72if Tff7b72selfTff7b72.Td2a8ff__track_phy_statsTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffq
Tff7b72elseTb4b4b4:
Tff7b72return Tff7b72None

Tff7b72def Td2a8ffget_establishment_rateTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: The data transfer rate at which the link establishment procedure ocurred, in bits per second.
"""
Tff7b72if Tff7b72selfTff7b72.Td2a8ffestablishment_rate Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffestablishment_rateTff7b72*T79c0ff8
Tff7b72elseTb4b4b4:
Tff7b72return Tff7b72None

Tff7b72def Td2a8ffget_mtuTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: The MTU of an established link.
"""
Tff7b72if Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3LinkTff7b72.Td2a8ffACTIVETb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffmtu
Tff7b72elseTb4b4b4:
Tff7b72return Tff7b72None

Tff7b72def Td2a8ffget_mduTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: The packet MDU of an established link.
"""
Tff7b72if Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3LinkTff7b72.Td2a8ffACTIVETb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffmdu
Tff7b72elseTb4b4b4:
Tff7b72return Tff7b72None

Tff7b72def Td2a8ffget_expected_rateTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: The packet expected in-flight data rate of an established link.
"""
Tff7b72if Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3LinkTff7b72.Td2a8ffACTIVETb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffexpected_rate
Tff7b72elseTb4b4b4:
Tff7b72return Tff7b72None

Tff7b72def Td2a8ffget_modeTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: The mode of an established link.
"""
Tff7b72return Tff7b72selfTff7b72.Td2a8ffmode

Tff7b72def Td2a8ffget_saltTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8fflink_id

Tff7b72def Td2a8ffget_contextTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72None

Tff7b72def Td2a8ffget_ageTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: The time in seconds since this link was established.
"""
Tff7b72if Tff7b72selfTff7b72.Td2a8ffactivated_atTb4b4b4:
Tff7b72return Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72- Tff7b72selfTff7b72.Td2a8ffactivated_at
Tff7b72elseTb4b4b4:
Tff7b72return Tff7b72None

Tff7b72def Td2a8ffno_inbound_forTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: The time in seconds since last inbound packet on the link. This includes keepalive packets.
"""
Te6edf3activated_at Tff7b72= Tff7b72selfTff7b72.Td2a8ffactivated_at Tff7b72if Tff7b72selfTff7b72.Td2a8ffactivated_at Tff7b72!= Tff7b72None Tff7b72else T79c0ff0
Te6edf3last_inbound Tff7b72= Tffa657maxTb4b4b4(Tff7b72selfTff7b72.Td2a8fflast_inboundTb4b4b4, Te6edf3activated_atTb4b4b4)
Tff7b72return Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3last_inbound

Tff7b72def Td2a8ffno_outbound_forTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: The time in seconds since last outbound packet on the link. This includes keepalive packets.
"""
Tff7b72return Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72- Tff7b72selfTff7b72.Td2a8fflast_outbound

Tff7b72def Td2a8ffno_data_forTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: The time in seconds since payload data traversed the link. This excludes keepalive packets.
"""
Tff7b72return Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72- Tff7b72selfTff7b72.Td2a8fflast_data

Tff7b72def Td2a8ffinactive_forTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: The time in seconds since activity on the link. This includes keepalive packets.
"""
Tff7b72return Tffa657minTb4b4b4(Tff7b72selfTff7b72.Td2a8ffno_inbound_forTb4b4b4(Tb4b4b4)Tb4b4b4, Tff7b72selfTff7b72.Td2a8ffno_outbound_forTb4b4b4(Tb4b4b4)Tb4b4b4)

Tff7b72def Td2a8ffget_remote_identityTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: The identity of the remote peer, if it is known. Calling this method will not query the remote initiator to reveal its identity. Returns ``None`` if the link initiator has not already independently called the ``identify(identity)`` method.
"""
Tff7b72return Tff7b72selfTff7b72.Td2a8ff__remote_identity

Tff7b72def Td2a8ffhad_outboundTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3is_keepaliveTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8fflast_outbound Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3is_keepaliveTb4b4b4: Tff7b72selfTff7b72.Td2a8fflast_data Tff7b72= Tff7b72selfTff7b72.Td2a8fflast_outbound
Tff7b72elseTb4b4b4: Tff7b72selfTff7b72.Td2a8fflast_keepalive Tff7b72= Tff7b72selfTff7b72.Td2a8fflast_outbound

Tff7b72def Td2a8ff__teardown_packetTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3teardown_packet Tff7b72= Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4(Tff7b72selfTb4b4b4, Tff7b72selfTff7b72.Td2a8fflink_idTb4b4b4, Te6edf3contextTff7b72=Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffLINKCLOSETb4b4b4)
Te6edf3teardown_packetTff7b72.Td2a8ffsendTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffhad_outboundTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffteardownTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
Closes the link and purges encryption keys. New keys will
be used if a new link to the same destination is established.
"""
Tff7b72if Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72!= Te6edf3LinkTff7b72.Td2a8ffPENDING Tff7b72and Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72!= Te6edf3LinkTff7b72.Td2a8ffCLOSEDTb4b4b4: Tff7b72selfTff7b72.Td2a8ff__teardown_packetTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3LinkTff7b72.Td2a8ffCLOSED
Tff7b72if Tff7b72selfTff7b72.Td2a8ffinitiatorTb4b4b4: Tff7b72selfTff7b72.Td2a8ffteardown_reason Tff7b72= Te6edf3LinkTff7b72.Td2a8ffINITIATOR_CLOSED
Tff7b72elseTb4b4b4: Tff7b72selfTff7b72.Td2a8ffteardown_reason Tff7b72= Te6edf3LinkTff7b72.Td2a8ffDESTINATION_CLOSED
Tff7b72selfTff7b72.Td2a8fflink_closedTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffteardown_packetTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3plaintext Tff7b72= Tff7b72selfTff7b72.Td2a8ffdecryptTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4)
Tff7b72if Te6edf3plaintext Tff7b72== Tff7b72selfTff7b72.Td2a8fflink_idTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3LinkTff7b72.Td2a8ffCLOSED
Tff7b72if Tff7b72selfTff7b72.Td2a8ffinitiatorTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffteardown_reason Tff7b72= Te6edf3LinkTff7b72.Td2a8ffDESTINATION_CLOSED
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffteardown_reason Tff7b72= Te6edf3LinkTff7b72.Td2a8ffINITIATOR_CLOSED
Tff7b72selfTff7b72.Td2a8ff__update_phy_statsTb4b4b4(Te6edf3packetTb4b4b4)
Tff7b72selfTff7b72.Td2a8fflink_closedTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72pass

Tff7b72def Td2a8fflink_closedTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3resource Tff7b72in Tff7b72selfTff7b72.Td2a8ffincoming_resourcesTb4b4b4: Te6edf3resourceTff7b72.Td2a8ffcancelTb4b4b4(Tb4b4b4)
Tff7b72for Te6edf3resource Tff7b72in Tff7b72selfTff7b72.Td2a8ffoutgoing_resourcesTb4b4b4: Te6edf3resourceTff7b72.Td2a8ffcancelTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_channelTb4b4b4: Tff7b72selfTff7b72.Td2a8ff_channelTff7b72.Td2a8ff_shutdownTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffprv Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffpub Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffpub_bytes Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffshared_key Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffderived_key Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffdestination Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffdirection Tff7b72== Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffINTb4b4b4:
Tff7b72if Tff7b72self Tff7b72in Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8fflinksTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8fflinksTff7b72.Td2a8ffremoveTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8fflink_closed Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72tryTb4b4b4: Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8fflink_closedTb4b4b4(Tff7b72selfTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while executing link closed callback from Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)


Tff7b72def Td2a8ffstart_watchdogTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Tff7b72selfTff7b72.Td2a8ff__watchdog_jobTb4b4b4)
Te6edf3threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff__watchdog_jobTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72while Tff7b72not Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3LinkTff7b72.Td2a8ffCLOSEDTb4b4b4:
Tff7b72while Tb4b4b4(Tff7b72selfTff7b72.Td2a8ffwatchdog_lockTb4b4b4)Tb4b4b4:
Te6edf3rtt_wait Tff7b72= T79c0ff0.025
Tff7b72if Tffa657hasattrTb4b4b4(Tff7b72selfTb4b4b4, Ta5d6ff"Ta5d6ffrttTa5d6ff"Tb4b4b4) Tff7b72and Tff7b72selfTff7b72.Td2a8ffrttTb4b4b4:
Te6edf3rtt_wait Tff7b72= Tff7b72selfTff7b72.Td2a8ffrtt

Te6edf3sleepTb4b4b4(Tffa657maxTb4b4b4(Te6edf3rtt_waitTb4b4b4, T79c0ff0.025Tb4b4b4)Tb4b4b4)

Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3LinkTff7b72.Td2a8ffCLOSEDTb4b4b4:
T8b949e# Link was initiated, but no response
T8b949e# from destination yet
Tff7b72if Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3LinkTff7b72.Td2a8ffPENDINGTb4b4b4:
Te6edf3next_check Tff7b72= Tff7b72selfTff7b72.Td2a8ffrequest_time Tff7b72+ Tff7b72selfTff7b72.Td2a8ffestablishment_timeout
Te6edf3sleep_time Tff7b72= Te6edf3next_check Tff7b72- Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72>Tff7b72= Tff7b72selfTff7b72.Td2a8ffrequest_time Tff7b72+ Tff7b72selfTff7b72.Td2a8ffestablishment_timeoutTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffLink establishment timed outTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3LinkTff7b72.Td2a8ffCLOSED
Tff7b72selfTff7b72.Td2a8ffteardown_reason Tff7b72= Te6edf3LinkTff7b72.Td2a8ffTIMEOUT
Tff7b72selfTff7b72.Td2a8fflink_closedTb4b4b4(Tb4b4b4)
Te6edf3sleep_time Tff7b72= T79c0ff0.001

Tff7b72elif Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3LinkTff7b72.Td2a8ffHANDSHAKETb4b4b4:
Te6edf3next_check Tff7b72= Tff7b72selfTff7b72.Td2a8ffrequest_time Tff7b72+ Tff7b72selfTff7b72.Td2a8ffestablishment_timeout
Te6edf3sleep_time Tff7b72= Te6edf3next_check Tff7b72- Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72>Tff7b72= Tff7b72selfTff7b72.Td2a8ffrequest_time Tff7b72+ Tff7b72selfTff7b72.Td2a8ffestablishment_timeoutTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3LinkTff7b72.Td2a8ffCLOSED
Tff7b72selfTff7b72.Td2a8ffteardown_reason Tff7b72= Te6edf3LinkTff7b72.Td2a8ffTIMEOUT
Tff7b72selfTff7b72.Td2a8fflink_closedTb4b4b4(Tb4b4b4)
Te6edf3sleep_time Tff7b72= T79c0ff0.001

Tff7b72if Tff7b72selfTff7b72.Td2a8ffinitiatorTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffTimeout waiting for link request proofTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffTimeout waiting for RTT packet from link initiatorTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)

Tff7b72elif Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3LinkTff7b72.Td2a8ffACTIVETb4b4b4:
Te6edf3activated_at Tff7b72= Tff7b72selfTff7b72.Td2a8ffactivated_at Tff7b72if Tff7b72selfTff7b72.Td2a8ffactivated_at Tff7b72!= Tff7b72None Tff7b72else T79c0ff0
Te6edf3last_inbound Tff7b72= Tffa657maxTb4b4b4(Tffa657maxTb4b4b4(Tff7b72selfTff7b72.Td2a8fflast_inboundTb4b4b4, Tff7b72selfTff7b72.Td2a8fflast_proofTb4b4b4)Tb4b4b4, Te6edf3activated_atTb4b4b4)
Te6edf3now Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)

Tff7b72if Te6edf3now Tff7b72>Tff7b72= Te6edf3last_inbound Tff7b72+ Tff7b72selfTff7b72.Td2a8ffkeepaliveTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffinitiator Tff7b72and Te6edf3now Tff7b72>Tff7b72= Tff7b72selfTff7b72.Td2a8fflast_keepalive Tff7b72+ Tff7b72selfTff7b72.Td2a8ffkeepaliveTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffsend_keepaliveTb4b4b4(Tb4b4b4)

Tff7b72if Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72>Tff7b72= Te6edf3last_inbound Tff7b72+ Tff7b72selfTff7b72.Td2a8ffstale_timeTb4b4b4:
Te6edf3sleep_time Tff7b72= Tff7b72selfTff7b72.Td2a8ffrtt Tff7b72* Tff7b72selfTff7b72.Td2a8ffkeepalive_timeout_factor Tff7b72+ Te6edf3LinkTff7b72.Td2a8ffSTALE_GRACE
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3LinkTff7b72.Td2a8ffSTALE
Tff7b72elseTb4b4b4:
Te6edf3sleep_time Tff7b72= Tff7b72selfTff7b72.Td2a8ffkeepalive
Tff7b72elseTb4b4b4:
Te6edf3sleep_time Tff7b72= Tb4b4b4(Te6edf3last_inbound Tff7b72+ Tff7b72selfTff7b72.Td2a8ffkeepaliveTb4b4b4) Tff7b72- Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)

Tff7b72elif Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3LinkTff7b72.Td2a8ffSTALETb4b4b4:
Te6edf3sleep_time Tff7b72= T79c0ff0.001
Tff7b72selfTff7b72.Td2a8ff__teardown_packetTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3LinkTff7b72.Td2a8ffCLOSED
Tff7b72selfTff7b72.Td2a8ffteardown_reason Tff7b72= Te6edf3LinkTff7b72.Td2a8ffTIMEOUT
Tff7b72selfTff7b72.Td2a8fflink_closedTb4b4b4(Tb4b4b4)


Tff7b72if Te6edf3sleep_time Tff7b72== T79c0ff0Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffWarning! Link watchdog sleep time of 0!Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72if Te6edf3sleep_time Tff7b72== Tff7b72None Tff7b72or Te6edf3sleep_time Tff7b72< T79c0ff0Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffTiming error! Tearing down link Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff now.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)
Te6edf3sleep_time Tff7b72= T79c0ff0.1

Te6edf3sleep_time Tff7b72= Tffa657minTb4b4b4(Te6edf3sleep_timeTb4b4b4, Te6edf3LinkTff7b72.Td2a8ffWATCHDOG_MAX_SLEEPTb4b4b4)
Te6edf3sleepTb4b4b4(Te6edf3sleep_timeTb4b4b4)

Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff__track_phy_statsTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrssi Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffsnr Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffq Tff7b72= Tff7b72None


Tff7b72def Td2a8ff__update_phy_statsTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4, Te6edf3query_shared Tff7b72= Tff7b72TrueTb4b4b4, Te6edf3force_update Tff7b72= Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff__track_phy_stats Tff7b72or Te6edf3force_updateTb4b4b4:
Tff7b72if Te6edf3query_sharedTb4b4b4:
Te6edf3reticulum Tff7b72= Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffget_instanceTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3packetTff7b72.Td2a8ffrssi Tff7b72== Tff7b72NoneTb4b4b4: Te6edf3packetTff7b72.Td2a8ffrssi Tff7b72= Te6edf3reticulumTff7b72.Td2a8ffget_packet_rssiTb4b4b4(Te6edf3packetTff7b72.Td2a8ffpacket_hashTb4b4b4)
Tff7b72if Te6edf3packetTff7b72.Td2a8ffsnr Tff7b72== Tff7b72NoneTb4b4b4: Te6edf3packetTff7b72.Td2a8ffsnr Tff7b72= Te6edf3reticulumTff7b72.Td2a8ffget_packet_snrTb4b4b4(Te6edf3packetTff7b72.Td2a8ffpacket_hashTb4b4b4)
Tff7b72if Te6edf3packetTff7b72.Td2a8ffq Tff7b72== Tff7b72NoneTb4b4b4: Te6edf3packetTff7b72.Td2a8ffq Tff7b72= Te6edf3reticulumTff7b72.Td2a8ffget_packet_qTb4b4b4(Te6edf3packetTff7b72.Td2a8ffpacket_hashTb4b4b4)

Tff7b72if Te6edf3packetTff7b72.Td2a8ffrssi Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrssi Tff7b72= Te6edf3packetTff7b72.Td2a8ffrssi
Tff7b72if Te6edf3packetTff7b72.Td2a8ffsnr Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffsnr Tff7b72= Te6edf3packetTff7b72.Td2a8ffsnr
Tff7b72if Te6edf3packetTff7b72.Td2a8ffq Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffq Tff7b72= Te6edf3packetTff7b72.Td2a8ffq

Tff7b72def Td2a8ff__update_keepaliveTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffkeepalive Tff7b72= Tffa657maxTb4b4b4(Tffa657minTb4b4b4(Tff7b72selfTff7b72.Td2a8ffrttTff7b72*Tb4b4b4(Te6edf3LinkTff7b72.Td2a8ffKEEPALIVE_MAXTff7b72/Te6edf3LinkTff7b72.Td2a8ffKEEPALIVE_MAX_RTTTb4b4b4)Tb4b4b4, Te6edf3LinkTff7b72.Td2a8ffKEEPALIVE_MAXTb4b4b4)Tb4b4b4, Te6edf3LinkTff7b72.Td2a8ffKEEPALIVE_MINTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffstale_time Tff7b72= Tff7b72selfTff7b72.Td2a8ffkeepalive Tff7b72* Te6edf3LinkTff7b72.Td2a8ffSTALE_FACTOR
Tff7b72def Td2a8ffsend_keepaliveTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3keepalive_packet Tff7b72= Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4(Tff7b72selfTb4b4b4, Tffa657bytesTb4b4b4(Tb4b4b4[T79c0ff0xFFTb4b4b4]Tb4b4b4)Tb4b4b4, Te6edf3contextTff7b72=Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffKEEPALIVETb4b4b4)
Te6edf3keepalive_packetTff7b72.Td2a8ffsendTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffhad_outboundTb4b4b4(Te6edf3is_keepalive Tff7b72= Tff7b72TrueTb4b4b4)

Tff7b72def Td2a8ffhandle_requestTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3request_idTb4b4b4, Te6edf3unpacked_requestTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3LinkTff7b72.Td2a8ffACTIVETb4b4b4:
Te6edf3requested_at Tff7b72= Te6edf3unpacked_requestTb4b4b4[T79c0ff0Tb4b4b4]
Te6edf3path_hash Tff7b72= Te6edf3unpacked_requestTb4b4b4[T79c0ff1Tb4b4b4]
Te6edf3request_data Tff7b72= Te6edf3unpacked_requestTb4b4b4[T79c0ff2Tb4b4b4]

Tff7b72if Te6edf3path_hash Tff7b72in Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffrequest_handlersTb4b4b4:
Te6edf3request_handler Tff7b72= Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffrequest_handlersTb4b4b4[Te6edf3path_hashTb4b4b4]
Te6edf3path Tff7b72= Te6edf3request_handlerTb4b4b4[T79c0ff0Tb4b4b4]
Te6edf3response_generator Tff7b72= Te6edf3request_handlerTb4b4b4[T79c0ff1Tb4b4b4]
Te6edf3allow Tff7b72= Te6edf3request_handlerTb4b4b4[T79c0ff2Tb4b4b4]
Te6edf3allowed_list Tff7b72= Te6edf3request_handlerTb4b4b4[T79c0ff3Tb4b4b4]
Te6edf3auto_compress Tff7b72= Te6edf3request_handlerTb4b4b4[T79c0ff4Tb4b4b4]

Te6edf3allowed Tff7b72= Tff7b72False
Tff7b72if Tff7b72not Te6edf3allow Tff7b72== Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffALLOW_NONETb4b4b4:
Tff7b72if Te6edf3allow Tff7b72== Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffALLOW_LISTTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff__remote_identity Tff7b72!= Tff7b72None Tff7b72and Tff7b72selfTff7b72.Td2a8ff__remote_identityTff7b72.Td2a8ffhash Tff7b72in Te6edf3allowed_listTb4b4b4:
Te6edf3allowed Tff7b72= Tff7b72True
Tff7b72elif Te6edf3allow Tff7b72== Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffALLOW_ALLTb4b4b4:
Te6edf3allowed Tff7b72= Tff7b72True

Tff7b72if Te6edf3allowedTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffHandling request Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3request_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff for: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3inspectTff7b72.Td2a8ffsignatureTb4b4b4(Te6edf3response_generatorTb4b4b4)Tff7b72.Td2a8ffparametersTb4b4b4) Tff7b72== T79c0ff5Tb4b4b4:
Te6edf3response Tff7b72= Te6edf3response_generatorTb4b4b4(Te6edf3pathTb4b4b4, Te6edf3request_dataTb4b4b4, Te6edf3request_idTb4b4b4, Tff7b72selfTff7b72.Td2a8ff__remote_identityTb4b4b4, Te6edf3requested_atTb4b4b4)
Tff7b72elif Tffa657lenTb4b4b4(Te6edf3inspectTff7b72.Td2a8ffsignatureTb4b4b4(Te6edf3response_generatorTb4b4b4)Tff7b72.Td2a8ffparametersTb4b4b4) Tff7b72== T79c0ff6Tb4b4b4:
Te6edf3response Tff7b72= Te6edf3response_generatorTb4b4b4(Te6edf3pathTb4b4b4, Te6edf3request_dataTb4b4b4, Te6edf3request_idTb4b4b4, Tff7b72selfTff7b72.Td2a8fflink_idTb4b4b4, Tff7b72selfTff7b72.Td2a8ff__remote_identityTb4b4b4, Te6edf3requested_atTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72raise Tf85149TypeErrorTb4b4b4(Ta5d6ff"Ta5d6ffInvalid signature for response generator callbackTa5d6ff"Tb4b4b4)

Te6edf3file_response Tff7b72= Tff7b72False
Te6edf3file_handle Tff7b72= Tff7b72None
Tff7b72if Tffa657typeTb4b4b4(Te6edf3responseTb4b4b4) Tff7b72== Tffa657list Tff7b72or Tffa657typeTb4b4b4(Te6edf3responseTb4b4b4) Tff7b72== Tffa657tupleTb4b4b4:
Te6edf3metadata Tff7b72= Tff7b72None
Tff7b72if Tffa657lenTb4b4b4(Te6edf3responseTb4b4b4) Tff7b72> T79c0ff0 Tff7b72and Tffa657typeTb4b4b4(Te6edf3responseTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4) Tff7b72== Te6edf3ioTff7b72.Td2a8ffBufferedReaderTb4b4b4:
Tff7b72if Tffa657lenTb4b4b4(Te6edf3responseTb4b4b4) Tff7b72> T79c0ff1Tb4b4b4: Te6edf3metadata Tff7b72= Te6edf3responseTb4b4b4[T79c0ff1Tb4b4b4]
Te6edf3file_handle Tff7b72= Te6edf3responseTb4b4b4[T79c0ff0Tb4b4b4]
Te6edf3file_response Tff7b72= Tff7b72True

Tff7b72if Te6edf3response Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72if Te6edf3file_responseTb4b4b4:
Te6edf3response_resource Tff7b72= Te6edf3RNSTff7b72.Td2a8ffResourceTb4b4b4(Te6edf3file_handleTb4b4b4, Tff7b72selfTb4b4b4, Te6edf3metadataTff7b72=Te6edf3metadataTb4b4b4, Te6edf3request_id Tff7b72= Te6edf3request_idTb4b4b4, Te6edf3is_response Tff7b72= Tff7b72TrueTb4b4b4, Te6edf3auto_compressTff7b72=Te6edf3auto_compressTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3packed_response Tff7b72= Te6edf3umsgpackTff7b72.Td2a8ffpackbTb4b4b4(Tb4b4b4[Te6edf3request_idTb4b4b4, Te6edf3responseTb4b4b4]Tb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3packed_responseTb4b4b4) Tff7b72<Tff7b72= Tff7b72selfTff7b72.Td2a8ffmduTb4b4b4:
Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packed_responseTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffDATATb4b4b4, Te6edf3context Tff7b72= Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffRESPONSETb4b4b4)Tff7b72.Td2a8ffsendTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3response_resource Tff7b72= Te6edf3RNSTff7b72.Td2a8ffResourceTb4b4b4(Te6edf3packed_responseTb4b4b4, Tff7b72selfTb4b4b4, Te6edf3request_id Tff7b72= Te6edf3request_idTb4b4b4, Te6edf3is_response Tff7b72= Tff7b72TrueTb4b4b4, Te6edf3auto_compressTff7b72=Te6edf3auto_compressTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3identity_string Tff7b72= Tffa657strTb4b4b4(Tff7b72selfTff7b72.Td2a8ffget_remote_identityTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72if Tff7b72selfTff7b72.Td2a8ffget_remote_identityTb4b4b4(Tb4b4b4) Tff7b72!= Tff7b72None Tff7b72else Ta5d6ff"Ta5d6ff<Unknown>Ta5d6ff"
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffRequest Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3request_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff from Ta5d6ff"Tff7b72+Te6edf3identity_stringTff7b72+Ta5d6ff"Ta5d6ff not allowed for: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)

Tff7b72def Td2a8ffhandle_responseTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3request_idTb4b4b4, Te6edf3response_dataTb4b4b4, Te6edf3response_sizeTb4b4b4, Te6edf3response_transfer_sizeTb4b4b4, Te6edf3metadataTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3LinkTff7b72.Td2a8ffACTIVETb4b4b4:
Te6edf3remove Tff7b72= Tff7b72None
Tff7b72for Te6edf3pending_request Tff7b72in Tff7b72selfTff7b72.Td2a8ffpending_requestsTb4b4b4:
Tff7b72if Te6edf3pending_requestTff7b72.Td2a8ffrequest_id Tff7b72== Te6edf3request_idTb4b4b4:
Te6edf3remove Tff7b72= Te6edf3pending_request
Tff7b72tryTb4b4b4:
Te6edf3pending_requestTff7b72.Td2a8ffresponse_size Tff7b72= Te6edf3response_size
Tff7b72if Te6edf3pending_requestTff7b72.Td2a8ffresponse_transfer_size Tff7b72== Tff7b72NoneTb4b4b4:
Te6edf3pending_requestTff7b72.Td2a8ffresponse_transfer_size Tff7b72= T79c0ff0
Te6edf3pending_requestTff7b72.Td2a8ffresponse_transfer_size Tff7b72+Tff7b72= Te6edf3response_transfer_size
Te6edf3pending_requestTff7b72.Td2a8ffresponse_receivedTb4b4b4(Te6edf3response_dataTb4b4b4, Te6edf3metadataTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError occurred while handling response. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72break

Tff7b72if Te6edf3remove Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72if Te6edf3remove Tff7b72in Tff7b72selfTff7b72.Td2a8ffpending_requestsTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpending_requestsTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3removeTb4b4b4)

Tff7b72def Td2a8ffrequest_resource_concludedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3resourceTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3resourceTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RNSTff7b72.Td2a8ffResourceTff7b72.Td2a8ffCOMPLETETb4b4b4:
Te6edf3packed_request Tff7b72= Te6edf3resourceTff7b72.Td2a8ffdataTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)
Te6edf3unpacked_request Tff7b72= Te6edf3umsgpackTff7b72.Td2a8ffunpackbTb4b4b4(Te6edf3packed_requestTb4b4b4)
Te6edf3request_id Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fftruncated_hashTb4b4b4(Te6edf3packed_requestTb4b4b4)
Te6edf3request_data Tff7b72= Te6edf3unpacked_request

Tff7b72def Td2a8ffjobTb4b4b4(Tb4b4b4)Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffhandle_requestTb4b4b4(Te6edf3request_idTb4b4b4, Te6edf3request_dataTb4b4b4)
Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3jobTb4b4b4, Te6edf3daemonTff7b72=Tff7b72TrueTb4b4b4)Tff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffIncoming request resource failed with status: Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Tb4b4b4[Te6edf3resourceTff7b72.Td2a8ffstatusTb4b4b4]Tb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)

Tff7b72def Td2a8ffresponse_resource_concludedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3resourceTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3resourceTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RNSTff7b72.Td2a8ffResourceTff7b72.Td2a8ffCOMPLETETb4b4b4:
T8b949e# If the response resource has metadata, this
T8b949e# is a file response, and we'll pass the open
T8b949e# file handle directly.
Tff7b72if Te6edf3resourceTff7b72.Td2a8ffhas_metadataTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffhandle_responseTb4b4b4(Te6edf3resourceTff7b72.Td2a8ffrequest_idTb4b4b4, Te6edf3resourceTff7b72.Td2a8ffdataTb4b4b4, Te6edf3resourceTff7b72.Td2a8fftotal_sizeTb4b4b4, Te6edf3resourceTff7b72.Td2a8ffsizeTb4b4b4, Te6edf3metadataTff7b72=Te6edf3resourceTff7b72.Td2a8ffmetadataTb4b4b4)

T8b949e# If not, we'll unpack the response data and
T8b949e# pass the unpacked structure to the handler
Tff7b72elseTb4b4b4:
Te6edf3packed_response Tff7b72= Te6edf3resourceTff7b72.Td2a8ffdataTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)
Te6edf3unpacked_response Tff7b72= Te6edf3umsgpackTff7b72.Td2a8ffunpackbTb4b4b4(Te6edf3packed_responseTb4b4b4)
Te6edf3request_id Tff7b72= Te6edf3unpacked_responseTb4b4b4[T79c0ff0Tb4b4b4]
Te6edf3response_data Tff7b72= Te6edf3unpacked_responseTb4b4b4[T79c0ff1Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffhandle_responseTb4b4b4(Te6edf3request_idTb4b4b4, Te6edf3response_dataTb4b4b4, Te6edf3resourceTff7b72.Td2a8fftotal_sizeTb4b4b4, Te6edf3resourceTff7b72.Td2a8ffsizeTb4b4b4)

Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffIncoming response resource failed with status: Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Tb4b4b4[Te6edf3resourceTff7b72.Td2a8ffstatusTb4b4b4]Tb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72for Te6edf3pending_request Tff7b72in Tff7b72selfTff7b72.Td2a8ffpending_requestsTb4b4b4:
Tff7b72if Te6edf3pending_requestTff7b72.Td2a8ffrequest_id Tff7b72== Te6edf3resourceTff7b72.Td2a8ffrequest_idTb4b4b4:
Te6edf3pending_requestTff7b72.Td2a8ffrequest_timed_outTb4b4b4(Tff7b72NoneTb4b4b4)

Tff7b72def Td2a8ffget_channelTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
Get the ``Channel`` for this link.

:return: ``Channel`` object
"""
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_channel Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_channel Tff7b72= Te6edf3ChannelTb4b4b4(Te6edf3LinkChannelOutletTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4)
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_channel

Tff7b72def Td2a8ffreceiveTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packetTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffwatchdog_lock Tff7b72= Tff7b72True
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3LinkTff7b72.Td2a8ffCLOSED Tff7b72and Tff7b72not Tb4b4b4(Tff7b72selfTff7b72.Td2a8ffinitiator Tff7b72and Te6edf3packetTff7b72.Td2a8ffcontext Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffKEEPALIVE Tff7b72and Te6edf3packetTff7b72.Td2a8ffdata Tff7b72== Tffa657bytesTb4b4b4(Tb4b4b4[T79c0ff0xFFTb4b4b4]Tb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3packetTff7b72.Td2a8ffreceiving_interface Tff7b72!= Tff7b72selfTff7b72.Td2a8ffattached_interfaceTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffLink-associated packet received on unexpected interface Tffd700{Te6edf3packetTff7b72.Td2a8ffreceiving_interfaceTffd700}Ta5d6ff instead of Tffd700{Tff7b72selfTff7b72.Td2a8ffattached_interfaceTffd700}Ta5d6ff! Someone might be trying to manipulate your communication!Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8fflast_inbound Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3packetTff7b72.Td2a8ffcontext Tff7b72!= Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffKEEPALIVETb4b4b4:
Tff7b72selfTff7b72.Td2a8fflast_data Tff7b72= Tff7b72selfTff7b72.Td2a8fflast_inbound
Tff7b72selfTff7b72.Td2a8ffrx Tff7b72+Tff7b72= T79c0ff1
Tff7b72selfTff7b72.Td2a8ffrxbytes Tff7b72+Tff7b72= Tffa657lenTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3LinkTff7b72.Td2a8ffSTALETb4b4b4:
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3LinkTff7b72.Td2a8ffACTIVE

Tff7b72if Te6edf3packetTff7b72.Td2a8ffpacket_type Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffDATATb4b4b4:
Te6edf3should_query Tff7b72= Tff7b72False
Tff7b72if Te6edf3packetTff7b72.Td2a8ffcontext Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffNONETb4b4b4:
Te6edf3plaintext Tff7b72= Tff7b72selfTff7b72.Td2a8ffdecryptTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4)
Te6edf3packetTff7b72.Td2a8ffratchet_id Tff7b72= Tff7b72selfTff7b72.Td2a8fflink_id
Tff7b72if Te6edf3plaintext Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff__update_phy_statsTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3query_sharedTff7b72=Tff7b72TrueTb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffpacket Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffpacketTb4b4b4, Te6edf3argsTff7b72=Tb4b4b4(Te6edf3plaintextTb4b4b4, Te6edf3packetTb4b4b4)Tb4b4b4)
Te6edf3threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffproof_strategy Tff7b72== Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffPROVE_ALLTb4b4b4:
Te6edf3packetTff7b72.Td2a8ffproveTb4b4b4(Tb4b4b4)

Tff7b72elif Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffproof_strategy Tff7b72== Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffPROVE_APPTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffproof_requestedTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffproof_requestedTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4:
Te6edf3packetTff7b72.Td2a8ffproveTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while executing proof request callback from Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72elif Te6edf3packetTff7b72.Td2a8ffcontext Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffLINKIDENTIFYTb4b4b4:
Te6edf3plaintext Tff7b72= Tff7b72selfTff7b72.Td2a8ffdecryptTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4)
Tff7b72if Te6edf3plaintext Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffinitiator Tff7b72and Tffa657lenTb4b4b4(Te6edf3plaintextTb4b4b4) Tff7b72== Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffKEYSIZETff7b72/Tff7b72/T79c0ff8 Tff7b72+ Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffSIGLENGTHTff7b72/Tff7b72/T79c0ff8Tb4b4b4:
Te6edf3public_key Tff7b72= Te6edf3plaintextTb4b4b4[Tb4b4b4:Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffKEYSIZETff7b72/Tff7b72/T79c0ff8Tb4b4b4]
Te6edf3signed_data Tff7b72= Tff7b72selfTff7b72.Td2a8fflink_idTff7b72+Te6edf3public_key
Te6edf3signature Tff7b72= Te6edf3plaintextTb4b4b4[Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffKEYSIZETff7b72/Tff7b72/T79c0ff8Tb4b4b4:Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffKEYSIZETff7b72/Tff7b72/T79c0ff8Tff7b72+Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffSIGLENGTHTff7b72/Tff7b72/T79c0ff8Tb4b4b4]
Te6edf3identity Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTb4b4b4(Te6edf3create_keysTff7b72=Tff7b72FalseTb4b4b4)
Te6edf3identityTff7b72.Td2a8ffload_public_keyTb4b4b4(Te6edf3public_keyTb4b4b4)

Tff7b72if Te6edf3identityTff7b72.Td2a8ffvalidateTb4b4b4(Te6edf3signatureTb4b4b4, Te6edf3signed_dataTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff__remote_identity Tff7b72= Te6edf3identity
Tff7b72if Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffremote_identified Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffremote_identifiedTb4b4b4(Tff7b72selfTb4b4b4, Tff7b72selfTff7b72.Td2a8ff__remote_identityTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while executing remote identified callback from Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff__update_phy_statsTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3query_sharedTff7b72=Tff7b72TrueTb4b4b4)

Tff7b72elif Te6edf3packetTff7b72.Td2a8ffcontext Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffREQUESTTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3request_id Tff7b72= Te6edf3packetTff7b72.Td2a8ffgetTruncatedHashTb4b4b4(Tb4b4b4)
Te6edf3packed_request Tff7b72= Tff7b72selfTff7b72.Td2a8ffdecryptTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4)
Tff7b72if Te6edf3packed_request Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3unpacked_request Tff7b72= Te6edf3umsgpackTff7b72.Td2a8ffunpackbTb4b4b4(Te6edf3packed_requestTb4b4b4)
Tff7b72def Td2a8ffjobTb4b4b4(Tb4b4b4)Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffhandle_requestTb4b4b4(Te6edf3request_idTb4b4b4, Te6edf3unpacked_requestTb4b4b4)
Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3jobTb4b4b4, Te6edf3daemonTff7b72=Tff7b72TrueTb4b4b4)Tff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff__update_phy_statsTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3query_sharedTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError occurred while handling request. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72elif Te6edf3packetTff7b72.Td2a8ffcontext Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffRESPONSETb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3packed_response Tff7b72= Tff7b72selfTff7b72.Td2a8ffdecryptTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4)
Tff7b72if Te6edf3packed_response Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3unpacked_response Tff7b72= Te6edf3umsgpackTff7b72.Td2a8ffunpackbTb4b4b4(Te6edf3packed_responseTb4b4b4)
Te6edf3request_id Tff7b72= Te6edf3unpacked_responseTb4b4b4[T79c0ff0Tb4b4b4]
Te6edf3response_data Tff7b72= Te6edf3unpacked_responseTb4b4b4[T79c0ff1Tb4b4b4]
Te6edf3transfer_size Tff7b72= Tffa657lenTb4b4b4(Te6edf3umsgpackTff7b72.Td2a8ffpackbTb4b4b4(Te6edf3response_dataTb4b4b4)Tb4b4b4)Tff7b72-T79c0ff2
Tff7b72def Td2a8ffjobTb4b4b4(Tb4b4b4)Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffhandle_responseTb4b4b4(Te6edf3request_idTb4b4b4, Te6edf3response_dataTb4b4b4, Te6edf3transfer_sizeTb4b4b4, Te6edf3transfer_sizeTb4b4b4)
Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3jobTb4b4b4, Te6edf3daemonTff7b72=Tff7b72TrueTb4b4b4)Tff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff__update_phy_statsTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3query_sharedTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError occurred while handling response. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72elif Te6edf3packetTff7b72.Td2a8ffcontext Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffLRRTTTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffinitiatorTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrtt_packetTb4b4b4(Te6edf3packetTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff__update_phy_statsTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3query_sharedTff7b72=Tff7b72TrueTb4b4b4)

Tff7b72elif Te6edf3packetTff7b72.Td2a8ffcontext Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffLINKCLOSETb4b4b4:
Tff7b72selfTff7b72.Td2a8ffteardown_packetTb4b4b4(Te6edf3packetTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff__update_phy_statsTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3query_sharedTff7b72=Tff7b72TrueTb4b4b4)

Tff7b72elif Te6edf3packetTff7b72.Td2a8ffcontext Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffRESOURCE_ADVTb4b4b4:
Te6edf3packetTff7b72.Td2a8ffplaintext Tff7b72= Tff7b72selfTff7b72.Td2a8ffdecryptTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4)
Tff7b72if Te6edf3packetTff7b72.Td2a8ffplaintext Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff__update_phy_statsTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3query_sharedTff7b72=Tff7b72TrueTb4b4b4)

Tff7b72if Te6edf3RNSTff7b72.Td2a8ffResourceAdvertisementTff7b72.Td2a8ffis_requestTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8ffResourceTff7b72.Td2a8ffacceptTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3callbackTff7b72=Tff7b72selfTff7b72.Td2a8ffrequest_resource_concludedTb4b4b4)
Tff7b72elif Te6edf3RNSTff7b72.Td2a8ffResourceAdvertisementTff7b72.Td2a8ffis_responseTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4:
Te6edf3request_id Tff7b72= Te6edf3RNSTff7b72.Td2a8ffResourceAdvertisementTff7b72.Td2a8ffread_request_idTb4b4b4(Te6edf3packetTb4b4b4)
Tff7b72for Te6edf3pending_request Tff7b72in Tff7b72selfTff7b72.Td2a8ffpending_requestsTb4b4b4:
Tff7b72if Te6edf3pending_requestTff7b72.Td2a8ffrequest_id Tff7b72== Te6edf3request_idTb4b4b4:
Te6edf3response_resource Tff7b72= Te6edf3RNSTff7b72.Td2a8ffResourceTff7b72.Td2a8ffacceptTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3callbackTff7b72=Tff7b72selfTff7b72.Td2a8ffresponse_resource_concludedTb4b4b4, Te6edf3progress_callbackTff7b72=Te6edf3pending_requestTff7b72.Td2a8ffresponse_resource_progressTb4b4b4, Te6edf3request_id Tff7b72= Te6edf3request_idTb4b4b4)
Tff7b72if Te6edf3response_resource Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72if Te6edf3pending_requestTff7b72.Td2a8ffresponse_size Tff7b72== Tff7b72NoneTb4b4b4:
Te6edf3pending_requestTff7b72.Td2a8ffresponse_size Tff7b72= Te6edf3RNSTff7b72.Td2a8ffResourceAdvertisementTff7b72.Td2a8ffread_sizeTb4b4b4(Te6edf3packetTb4b4b4)
Tff7b72if Te6edf3pending_requestTff7b72.Td2a8ffresponse_transfer_size Tff7b72== Tff7b72NoneTb4b4b4:
Te6edf3pending_requestTff7b72.Td2a8ffresponse_transfer_size Tff7b72= T79c0ff0
Te6edf3pending_requestTff7b72.Td2a8ffresponse_transfer_size Tff7b72+Tff7b72= Te6edf3RNSTff7b72.Td2a8ffResourceAdvertisementTff7b72.Td2a8ffread_transfer_sizeTb4b4b4(Te6edf3packetTb4b4b4)
Tff7b72if Te6edf3pending_requestTff7b72.Td2a8ffstarted_at Tff7b72== Tff7b72NoneTb4b4b4:
Te6edf3pending_requestTff7b72.Td2a8ffstarted_at Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Te6edf3pending_requestTff7b72.Td2a8ffresponse_resource_progressTb4b4b4(Te6edf3response_resourceTb4b4b4)

Tff7b72elif Tff7b72selfTff7b72.Td2a8ffresource_strategy Tff7b72== Te6edf3LinkTff7b72.Td2a8ffACCEPT_NONETb4b4b4: Tff7b72pass
Tff7b72elif Tff7b72selfTff7b72.Td2a8ffresource_strategy Tff7b72== Te6edf3LinkTff7b72.Td2a8ffACCEPT_APPTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffresource Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3resource_advertisement Tff7b72= Te6edf3RNSTff7b72.Td2a8ffResourceAdvertisementTff7b72.Td2a8ffunpackTb4b4b4(Te6edf3packetTff7b72.Td2a8ffplaintextTb4b4b4)
Te6edf3resource_advertisementTff7b72.Td2a8fflink Tff7b72= Tff7b72self
Tff7b72if Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffresourceTb4b4b4(Te6edf3resource_advertisementTb4b4b4)Tb4b4b4: Te6edf3RNSTff7b72.Td2a8ffResourceTff7b72.Td2a8ffacceptTb4b4b4(Te6edf3packetTb4b4b4, Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffresource_concludedTb4b4b4)
Tff7b72elseTb4b4b4: Te6edf3RNSTff7b72.Td2a8ffResourceTff7b72.Td2a8ffrejectTb4b4b4(Te6edf3packetTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while executing resource accept callback from Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72elif Tff7b72selfTff7b72.Td2a8ffresource_strategy Tff7b72== Te6edf3LinkTff7b72.Td2a8ffACCEPT_ALLTb4b4b4:
Te6edf3RNSTff7b72.Td2a8ffResourceTff7b72.Td2a8ffacceptTb4b4b4(Te6edf3packetTb4b4b4, Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffresource_concludedTb4b4b4)

Tff7b72elif Te6edf3packetTff7b72.Td2a8ffcontext Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffRESOURCE_REQTb4b4b4:
Te6edf3plaintext Tff7b72= Tff7b72selfTff7b72.Td2a8ffdecryptTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4)
Tff7b72if Te6edf3plaintext Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff__update_phy_statsTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3query_sharedTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72if Tffa657ordTb4b4b4(Te6edf3plaintextTb4b4b4[Tb4b4b4:T79c0ff1Tb4b4b4]Tb4b4b4) Tff7b72== Te6edf3RNSTff7b72.Td2a8ffResourceTff7b72.Td2a8ffHASHMAP_IS_EXHAUSTEDTb4b4b4:
Te6edf3resource_hash Tff7b72= Te6edf3plaintextTb4b4b4[T79c0ff1Tff7b72+Te6edf3RNSTff7b72.Td2a8ffResourceTff7b72.Td2a8ffMAPHASH_LENTb4b4b4:Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffHASHLENGTHTff7b72/Tff7b72/T79c0ff8Tff7b72+T79c0ff1Tff7b72+Te6edf3RNSTff7b72.Td2a8ffResourceTff7b72.Td2a8ffMAPHASH_LENTb4b4b4]
Tff7b72elseTb4b4b4:
Te6edf3resource_hash Tff7b72= Te6edf3plaintextTb4b4b4[T79c0ff1Tb4b4b4:Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffHASHLENGTHTff7b72/Tff7b72/T79c0ff8Tff7b72+T79c0ff1Tb4b4b4]

Tff7b72for Te6edf3resource Tff7b72in Tff7b72selfTff7b72.Td2a8ffoutgoing_resourcesTb4b4b4:
Tff7b72if Te6edf3resourceTff7b72.Td2a8ffhash Tff7b72== Te6edf3resource_hashTb4b4b4:
T8b949e# We need to check that this request has not been
T8b949e# received before in order to avoid sequencing errors.
Tff7b72if Tff7b72not Te6edf3packetTff7b72.Td2a8ffpacket_hash Tff7b72in Te6edf3resourceTff7b72.Td2a8ffreq_hashlistTb4b4b4:
Te6edf3resourceTff7b72.Td2a8ffreq_hashlistTff7b72.Td2a8ffappendTb4b4b4(Te6edf3packetTff7b72.Td2a8ffpacket_hashTb4b4b4)
Te6edf3resourceTff7b72.Td2a8ffrequestTb4b4b4(Te6edf3plaintextTb4b4b4)
T8b949e# TODO: Test and possibly enable this at some point
T8b949e# def request_job():
T8b949e# resource.request(plaintext)
T8b949e# threading.Thread(target=request_job, daemon=True).start()

Tff7b72elif Te6edf3packetTff7b72.Td2a8ffcontext Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffRESOURCE_HMUTb4b4b4:
Te6edf3plaintext Tff7b72= Tff7b72selfTff7b72.Td2a8ffdecryptTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4)
Tff7b72if Te6edf3plaintext Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff__update_phy_statsTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3query_sharedTff7b72=Tff7b72TrueTb4b4b4)
Te6edf3resource_hash Tff7b72= Te6edf3plaintextTb4b4b4[Tb4b4b4:Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffHASHLENGTHTff7b72/Tff7b72/T79c0ff8Tb4b4b4]
Tff7b72for Te6edf3resource Tff7b72in Tff7b72selfTff7b72.Td2a8ffincoming_resourcesTb4b4b4:
Tff7b72if Te6edf3resource_hash Tff7b72== Te6edf3resourceTff7b72.Td2a8ffhashTb4b4b4:
Te6edf3resourceTff7b72.Td2a8ffhashmap_update_packetTb4b4b4(Te6edf3plaintextTb4b4b4)

Tff7b72elif Te6edf3packetTff7b72.Td2a8ffcontext Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffRESOURCE_ICLTb4b4b4:
Te6edf3plaintext Tff7b72= Tff7b72selfTff7b72.Td2a8ffdecryptTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4)
Tff7b72if Te6edf3plaintext Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff__update_phy_statsTb4b4b4(Te6edf3packetTb4b4b4)
Te6edf3resource_hash Tff7b72= Te6edf3plaintextTb4b4b4[Tb4b4b4:Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffHASHLENGTHTff7b72/Tff7b72/T79c0ff8Tb4b4b4]
Tff7b72for Te6edf3resource Tff7b72in Tff7b72selfTff7b72.Td2a8ffincoming_resourcesTb4b4b4:
Tff7b72if Te6edf3resource_hash Tff7b72== Te6edf3resourceTff7b72.Td2a8ffhashTb4b4b4:
Te6edf3resourceTff7b72.Td2a8ffcancelTb4b4b4(Tb4b4b4)

Tff7b72elif Te6edf3packetTff7b72.Td2a8ffcontext Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffRESOURCE_RCLTb4b4b4:
Te6edf3plaintext Tff7b72= Tff7b72selfTff7b72.Td2a8ffdecryptTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4)
Tff7b72if Te6edf3plaintext Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff__update_phy_statsTb4b4b4(Te6edf3packetTb4b4b4)
Te6edf3resource_hash Tff7b72= Te6edf3plaintextTb4b4b4[Tb4b4b4:Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffHASHLENGTHTff7b72/Tff7b72/T79c0ff8Tb4b4b4]
Tff7b72for Te6edf3resource Tff7b72in Tff7b72selfTff7b72.Td2a8ffoutgoing_resourcesTb4b4b4:
Tff7b72if Te6edf3resource_hash Tff7b72== Te6edf3resourceTff7b72.Td2a8ffhashTb4b4b4:
Te6edf3resourceTff7b72.Td2a8ff_rejectedTb4b4b4(Tb4b4b4)

Tff7b72elif Te6edf3packetTff7b72.Td2a8ffcontext Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffKEEPALIVETb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffinitiator Tff7b72and Te6edf3packetTff7b72.Td2a8ffdata Tff7b72== Tffa657bytesTb4b4b4(Tb4b4b4[T79c0ff0xFFTb4b4b4]Tb4b4b4)Tb4b4b4:
Te6edf3keepalive_packet Tff7b72= Te6edf3RNSTff7b72.Td2a8ffPacketTb4b4b4(Tff7b72selfTb4b4b4, Tffa657bytesTb4b4b4(Tb4b4b4[T79c0ff0xFETb4b4b4]Tb4b4b4)Tb4b4b4, Te6edf3contextTff7b72=Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffKEEPALIVETb4b4b4)
Te6edf3keepalive_packetTff7b72.Td2a8ffsendTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffhad_outboundTb4b4b4(Te6edf3is_keepalive Tff7b72= Tff7b72TrueTb4b4b4)


T8b949e# TODO: find the most efficient way to allow multiple
T8b949e# transfers at the same time, sending resource hash on
T8b949e# each packet is a huge overhead. Probably some kind
T8b949e# of hash -> sequence map
Tff7b72elif Te6edf3packetTff7b72.Td2a8ffcontext Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffRESOURCETb4b4b4:
Tff7b72for Te6edf3resource Tff7b72in Tff7b72selfTff7b72.Td2a8ffincoming_resourcesTb4b4b4:
Te6edf3resourceTff7b72.Td2a8ffreceive_partTb4b4b4(Te6edf3packetTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff__update_phy_statsTb4b4b4(Te6edf3packetTb4b4b4)

Tff7b72elif Te6edf3packetTff7b72.Td2a8ffcontext Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffCHANNELTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_channelTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffChannel data received without open channelTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3packetTff7b72.Td2a8ffproveTb4b4b4(Tb4b4b4)
Te6edf3plaintext Tff7b72= Tff7b72selfTff7b72.Td2a8ffdecryptTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4)
Tff7b72if Te6edf3plaintext Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff__update_phy_statsTb4b4b4(Te6edf3packetTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_channelTff7b72.Td2a8ff_receiveTb4b4b4(Te6edf3plaintextTb4b4b4)

Tff7b72elif Te6edf3packetTff7b72.Td2a8ffpacket_type Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffPROOFTb4b4b4:
Tff7b72if Te6edf3packetTff7b72.Td2a8ffcontext Tff7b72== Te6edf3RNSTff7b72.Td2a8ffPacketTff7b72.Td2a8ffRESOURCE_PRFTb4b4b4:
Te6edf3resource_hash Tff7b72= Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4[T79c0ff0Tb4b4b4:Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffHASHLENGTHTff7b72/Tff7b72/T79c0ff8Tb4b4b4]
Tff7b72for Te6edf3resource Tff7b72in Tff7b72selfTff7b72.Td2a8ffoutgoing_resourcesTb4b4b4:
Tff7b72if Te6edf3resource_hash Tff7b72== Te6edf3resourceTff7b72.Td2a8ffhashTb4b4b4:
Tff7b72def Td2a8ffjobTb4b4b4(Te6edf3resourceTff7b72=Te6edf3resourceTb4b4b4)Tb4b4b4: Te6edf3resourceTff7b72.Td2a8ffvalidate_proofTb4b4b4(Te6edf3packetTff7b72.Td2a8ffdataTb4b4b4)
Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3jobTb4b4b4, Te6edf3daemonTff7b72=Tff7b72TrueTb4b4b4)Tff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff__update_phy_statsTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3query_sharedTff7b72=Tff7b72TrueTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffwatchdog_lock Tff7b72= Tff7b72False


Tff7b72def Td2a8ffencryptTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3plaintextTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8fftokenTb4b4b4:
Tff7b72tryTb4b4b4: Tff7b72selfTff7b72.Td2a8fftoken Tff7b72= Te6edf3TokenTb4b4b4(Tff7b72selfTff7b72.Td2a8ffderived_keyTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCould not instantiate token while performing encryption on link Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72raise Te6edf3e

Tff7b72return Tff7b72selfTff7b72.Td2a8fftokenTff7b72.Td2a8ffencryptTb4b4b4(Te6edf3plaintextTb4b4b4)

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffEncryption on link Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff failed. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72raise Te6edf3e


Tff7b72def Td2a8ffdecryptTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3ciphertextTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8fftokenTb4b4b4: Tff7b72selfTff7b72.Td2a8fftoken Tff7b72= Te6edf3TokenTb4b4b4(Tff7b72selfTff7b72.Td2a8ffderived_keyTb4b4b4)
Tff7b72return Tff7b72selfTff7b72.Td2a8fftokenTff7b72.Td2a8ffdecryptTb4b4b4(Te6edf3ciphertextTb4b4b4)

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffDecryption failed on link Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72return Tff7b72None


Tff7b72def Td2a8ffsignTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3messageTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffsig_prvTff7b72.Td2a8ffsignTb4b4b4(Te6edf3messageTb4b4b4)

Tff7b72def Td2a8ffvalidateTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3signatureTb4b4b4, Te6edf3messageTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpeer_sig_pubTff7b72.Td2a8ffverifyTb4b4b4(Te6edf3signatureTb4b4b4, Te6edf3messageTb4b4b4)
Tff7b72return Tff7b72True
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Tff7b72False

Tff7b72def Td2a8ffset_link_established_callbackTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3callbackTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8fflink_established Tff7b72= Te6edf3callback

Tff7b72def Td2a8ffset_link_closed_callbackTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3callbackTb4b4b4)Tb4b4b4:
T8b949e"""
Registers a function to be called when a link has been
torn down.

:param callback: A function or method with the signature *callback(link)* to be called.
"""
Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8fflink_closed Tff7b72= Te6edf3callback

Tff7b72def Td2a8ffset_packet_callbackTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3callbackTb4b4b4)Tb4b4b4:
T8b949e"""
Registers a function to be called when a packet has been
received over this link.

:param callback: A function or method with the signature *callback(message, packet)* to be called.
"""
Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffpacket Tff7b72= Te6edf3callback

Tff7b72def Td2a8ffset_resource_callbackTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3callbackTb4b4b4)Tb4b4b4:
T8b949e"""
Registers a function to be called when a resource has been
advertised over this link. If the function returns *True*
the resource will be accepted. If it returns *False* it will
be ignored.

:param callback: A function or method with the signature *callback(resource)* to be called. Please note that only the basic information of the resource is available at this time, such as *get_transfer_size()*, *get_data_size()*, *get_parts()* and *is_compressed()*.
"""
Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffresource Tff7b72= Te6edf3callback

Tff7b72def Td2a8ffset_resource_started_callbackTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3callbackTb4b4b4)Tb4b4b4:
T8b949e"""
Registers a function to be called when a resource has begun
transferring over this link.

:param callback: A function or method with the signature *callback(resource)* to be called.
"""
Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffresource_started Tff7b72= Te6edf3callback

Tff7b72def Td2a8ffset_resource_concluded_callbackTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3callbackTb4b4b4)Tb4b4b4:
T8b949e"""
Registers a function to be called when a resource has concluded
transferring over this link.

:param callback: A function or method with the signature *callback(resource)* to be called.
"""
Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffresource_concluded Tff7b72= Te6edf3callback

Tff7b72def Td2a8ffset_remote_identified_callbackTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3callbackTb4b4b4)Tb4b4b4:
T8b949e"""
Registers a function to be called when an initiating peer has
identified over this link.

:param callback: A function or method with the signature *callback(link, identity)* to be called.
"""
Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffremote_identified Tff7b72= Te6edf3callback

Tff7b72def Td2a8ffresource_concludedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3resourceTb4b4b4)Tb4b4b4:
Te6edf3concluded_at Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3resource Tff7b72in Tff7b72selfTff7b72.Td2a8ffincoming_resourcesTb4b4b4:
Tff7b72selfTff7b72.Td2a8fflast_resource_window Tff7b72= Te6edf3resourceTff7b72.Td2a8ffwindow
Tff7b72selfTff7b72.Td2a8fflast_resource_eifr Tff7b72= Te6edf3resourceTff7b72.Td2a8ffeifr
Tff7b72selfTff7b72.Td2a8ffincoming_resourcesTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3resourceTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffexpected_rate Tff7b72= Tb4b4b4(Te6edf3resourceTff7b72.Td2a8ffsizeTff7b72*T79c0ff8Tb4b4b4)Tff7b72/Tb4b4b4(Tffa657maxTb4b4b4(Te6edf3concluded_atTff7b72-Te6edf3resourceTff7b72.Td2a8ffstarted_transferringTb4b4b4, T79c0ff0.0001Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3resource Tff7b72in Tff7b72selfTff7b72.Td2a8ffoutgoing_resourcesTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffoutgoing_resourcesTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3resourceTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffexpected_rate Tff7b72= Tb4b4b4(Te6edf3resourceTff7b72.Td2a8ffsizeTff7b72*T79c0ff8Tb4b4b4)Tff7b72/Tb4b4b4(Tffa657maxTb4b4b4(Te6edf3concluded_atTff7b72-Te6edf3resourceTff7b72.Td2a8ffstarted_transferringTb4b4b4, T79c0ff0.0001Tb4b4b4)Tb4b4b4)

Tff7b72def Td2a8ffset_resource_strategyTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3resource_strategyTb4b4b4)Tb4b4b4:
T8b949e"""
Sets the resource strategy for the link.

:param resource_strategy: One of ``RNS.Link.ACCEPT_NONE``, ``RNS.Link.ACCEPT_ALL`` or ``RNS.Link.ACCEPT_APP``. If ``RNS.Link.ACCEPT_APP`` is set, the `resource_callback` will be called to determine whether the resource should be accepted or not.
:raises: *TypeError* if the resource strategy is unsupported.
"""
Tff7b72if Tff7b72not Te6edf3resource_strategy Tff7b72in Te6edf3LinkTff7b72.Td2a8ffresource_strategiesTb4b4b4: Tff7b72raise Tf85149TypeErrorTb4b4b4(Ta5d6ff"Ta5d6ffUnsupported resource strategyTa5d6ff"Tb4b4b4)
Tff7b72elseTb4b4b4: Tff7b72selfTff7b72.Td2a8ffresource_strategy Tff7b72= Te6edf3resource_strategy

Tff7b72def Td2a8ffregister_outgoing_resourceTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3resourceTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffoutgoing_resourcesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3resourceTb4b4b4)

Tff7b72def Td2a8ffregister_incoming_resourceTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3resourceTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffincoming_resourcesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3resourceTb4b4b4)

Tff7b72def Td2a8ffhas_incoming_resourceTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3resourceTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3incoming_resource Tff7b72in Tff7b72selfTff7b72.Td2a8ffincoming_resourcesTb4b4b4:
Tff7b72if Te6edf3incoming_resourceTff7b72.Td2a8ffhash Tff7b72== Te6edf3resourceTff7b72.Td2a8ffhashTb4b4b4: Tff7b72return Tff7b72True

Tff7b72return Tff7b72False

Tff7b72def Td2a8ffget_last_resource_windowTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8fflast_resource_window

Tff7b72def Td2a8ffget_last_resource_eifrTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8fflast_resource_eifr

Tff7b72def Td2a8ffcancel_outgoing_resourceTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3resourceTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3resource Tff7b72in Tff7b72selfTff7b72.Td2a8ffoutgoing_resourcesTb4b4b4: Tff7b72selfTff7b72.Td2a8ffoutgoing_resourcesTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3resourceTb4b4b4)
Tff7b72elseTb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffAttempt to cancel a non-existing outgoing resourceTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_WARNINGTb4b4b4)

Tff7b72def Td2a8ffcancel_incoming_resourceTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3resourceTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3resource Tff7b72in Tff7b72selfTff7b72.Td2a8ffincoming_resourcesTb4b4b4: Tff7b72selfTff7b72.Td2a8ffincoming_resourcesTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3resourceTb4b4b4)
Tff7b72elseTb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffAttempt to cancel a non-existing incoming resourceTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_WARNINGTb4b4b4)

Tff7b72def Td2a8ffready_for_new_resourceTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ffoutgoing_resourcesTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4: Tff7b72return Tff7b72False
Tff7b72elseTb4b4b4: Tff7b72return Tff7b72True

Tff7b72def Tff7b72__str__Tb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4: Tff7b72return Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Tff7b72selfTff7b72.Td2a8fflink_idTb4b4b4)


Tff7b72class T56d364RequestReceiptTb4b4b4(Tb4b4b4)Tb4b4b4:
T8b949e"""
An instance of this class is returned by the ``request`` method of ``RNS.Link``
instances. It should never be instantiated manually. It provides methods to
check status, response time and response data when the request concludes.
"""

Te6edf3FAILED Tff7b72= T79c0ff0x00
Te6edf3SENT Tff7b72= T79c0ff0x01
Te6edf3DELIVERED Tff7b72= T79c0ff0x02
Te6edf3RECEIVING Tff7b72= T79c0ff0x03
Te6edf3READY Tff7b72= T79c0ff0x04

Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3linkTb4b4b4, Te6edf3packet_receipt Tff7b72= Tff7b72NoneTb4b4b4, Te6edf3resource Tff7b72= Tff7b72NoneTb4b4b4, Te6edf3response_callback Tff7b72= Tff7b72NoneTb4b4b4, Te6edf3failed_callback Tff7b72= Tff7b72NoneTb4b4b4, Te6edf3progress_callback Tff7b72= Tff7b72NoneTb4b4b4, Te6edf3timeout Tff7b72= Tff7b72NoneTb4b4b4, Te6edf3request_size Tff7b72= Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpacket_receipt Tff7b72= Te6edf3packet_receipt
Tff7b72selfTff7b72.Td2a8ffresource Tff7b72= Te6edf3resource
Tff7b72selfTff7b72.Td2a8ffstarted_at Tff7b72= Tff7b72None

Tff7b72if Tff7b72selfTff7b72.Td2a8ffpacket_receipt Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffhash Tff7b72= Te6edf3packet_receiptTff7b72.Td2a8fftruncated_hash
Tff7b72selfTff7b72.Td2a8ffpacket_receiptTff7b72.Td2a8ffset_timeout_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffrequest_timed_outTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffstarted_at Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)

Tff7b72elif Tff7b72selfTff7b72.Td2a8ffresource Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffhash Tff7b72= Te6edf3resourceTff7b72.Td2a8ffrequest_id
Te6edf3resourceTff7b72.Td2a8ffset_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffrequest_resource_concludedTb4b4b4)
Tff7b72selfTff7b72.Td2a8fflink Tff7b72= Te6edf3link
Tff7b72selfTff7b72.Td2a8ffrequest_id Tff7b72= Tff7b72selfTff7b72.Td2a8ffhash
Tff7b72selfTff7b72.Td2a8ffrequest_size Tff7b72= Te6edf3request_size

Tff7b72selfTff7b72.Td2a8ffresponse Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffresponse_transfer_size Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffresponse_size Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffmetadata Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3RequestReceiptTff7b72.Td2a8ffSENT
Tff7b72selfTff7b72.Td2a8ffsent_at Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffprogress Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ffconcluded_at Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffresponse_concluded_at Tff7b72= Tff7b72None

Tff7b72if Te6edf3timeout Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8fftimeout Tff7b72= Te6edf3timeout
Tff7b72elseTb4b4b4:
Tff7b72raise Tf85149ValueErrorTb4b4b4(Ta5d6ff"Ta5d6ffNo timeout specified for request receiptTa5d6ff"Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffcallbacks Tff7b72= Te6edf3RequestReceiptCallbacksTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffresponse Tff7b72= Te6edf3response_callback
Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8fffailed Tff7b72= Te6edf3failed_callback
Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffprogress Tff7b72= Te6edf3progress_callback

Tff7b72selfTff7b72.Td2a8fflinkTff7b72.Td2a8ffpending_requestsTff7b72.Td2a8ffappendTb4b4b4(Tff7b72selfTb4b4b4)


Tff7b72def Td2a8ffrequest_resource_concludedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3resourceTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3resourceTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RNSTff7b72.Td2a8ffResourceTff7b72.Td2a8ffCOMPLETETb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffRequest Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Tff7b72selfTff7b72.Td2a8ffrequest_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff successfully sent as resource.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffstarted_at Tff7b72== Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffstarted_at Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3RequestReceiptTff7b72.Td2a8ffDELIVERED
Tff7b72selfTff7b72.Td2a8ff__resource_response_timeout Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)Tff7b72+Tff7b72selfTff7b72.Td2a8fftimeout
Te6edf3response_timeout_thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Tff7b72selfTff7b72.Td2a8ff__response_timeout_jobTb4b4b4)
Te6edf3response_timeout_threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3response_timeout_threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffSending request Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Tff7b72selfTff7b72.Td2a8ffrequest_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff as resource failed with status: Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Tb4b4b4[Te6edf3resourceTff7b72.Td2a8ffstatusTb4b4b4]Tb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3RequestReceiptTff7b72.Td2a8ffFAILED
Tff7b72selfTff7b72.Td2a8ffconcluded_at Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflinkTff7b72.Td2a8ffpending_requestsTff7b72.Td2a8ffremoveTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8fffailed Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8fffailedTb4b4b4(Tff7b72selfTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while executing request failed callback from Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)


Tff7b72def Td2a8ff__response_timeout_jobTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72while Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RequestReceiptTff7b72.Td2a8ffDELIVEREDTb4b4b4:
Te6edf3now Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3now Tff7b72> Tff7b72selfTff7b72.Td2a8ff__resource_response_timeoutTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrequest_timed_outTb4b4b4(Tff7b72NoneTb4b4b4)
Tff7b72break

Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.1Tb4b4b4)


Tff7b72def Td2a8ffrequest_timed_outTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3packet_receiptTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72self Tff7b72in Tff7b72selfTff7b72.Td2a8fflinkTff7b72.Td2a8ffpending_requests Tff7b72and Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RequestReceiptTff7b72.Td2a8ffDELIVEREDTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3RequestReceiptTff7b72.Td2a8ffFAILED
Tff7b72selfTff7b72.Td2a8ffconcluded_at Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflinkTff7b72.Td2a8ffpending_requestsTff7b72.Td2a8ffremoveTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8fffailed Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72tryTb4b4b4: Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8fffailedTb4b4b4(Tff7b72selfTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while executing request timed out callback from Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)


Tff7b72def Td2a8ffresponse_resource_progressTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3resourceTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3resource Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RequestReceiptTff7b72.Td2a8ffFAILEDTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3RequestReceiptTff7b72.Td2a8ffRECEIVING
Tff7b72if Tff7b72selfTff7b72.Td2a8ffpacket_receipt Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffpacket_receiptTff7b72.Td2a8ffstatus Tff7b72!= Te6edf3RNSTff7b72.Td2a8ffPacketReceiptTff7b72.Td2a8ffDELIVEREDTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpacket_receiptTff7b72.Td2a8ffstatus Tff7b72= Te6edf3RNSTff7b72.Td2a8ffPacketReceiptTff7b72.Td2a8ffDELIVERED
Tff7b72selfTff7b72.Td2a8ffpacket_receiptTff7b72.Td2a8ffproved Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffpacket_receiptTff7b72.Td2a8ffconcluded_at Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffpacket_receiptTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffdelivery Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpacket_receiptTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffdeliveryTb4b4b4(Tff7b72selfTff7b72.Td2a8ffpacket_receiptTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffprogress Tff7b72= Te6edf3resourceTff7b72.Td2a8ffget_progressTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffprogress Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffprogressTb4b4b4(Tff7b72selfTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while executing response progress callback from Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3resourceTff7b72.Td2a8ffcancelTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffresponse_receivedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3responseTb4b4b4, Te6edf3metadataTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RequestReceiptTff7b72.Td2a8ffFAILEDTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffprogress Tff7b72= T79c0ff1.0
Tff7b72selfTff7b72.Td2a8ffresponse Tff7b72= Te6edf3response
Tff7b72selfTff7b72.Td2a8ffmetadata Tff7b72= Te6edf3metadata
Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72= Te6edf3RequestReceiptTff7b72.Td2a8ffREADY
Tff7b72selfTff7b72.Td2a8ffresponse_concluded_at Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffpacket_receipt Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpacket_receiptTff7b72.Td2a8ffstatus Tff7b72= Te6edf3RNSTff7b72.Td2a8ffPacketReceiptTff7b72.Td2a8ffDELIVERED
Tff7b72selfTff7b72.Td2a8ffpacket_receiptTff7b72.Td2a8ffproved Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffpacket_receiptTff7b72.Td2a8ffconcluded_at Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffpacket_receiptTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffdelivery Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpacket_receiptTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffdeliveryTb4b4b4(Tff7b72selfTff7b72.Td2a8ffpacket_receiptTb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffprogress Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72tryTb4b4b4: Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffprogressTb4b4b4(Tff7b72selfTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while executing response progress callback from Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffresponse Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72tryTb4b4b4: Tff7b72selfTff7b72.Td2a8ffcallbacksTff7b72.Td2a8ffresponseTb4b4b4(Tff7b72selfTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while executing response received callback from Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72def Td2a8ffget_request_idTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: The request ID as *bytes*.
"""
Tff7b72return Tff7b72selfTff7b72.Td2a8ffrequest_id

Tff7b72def Td2a8ffget_statusTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: The current status of the request, one of ``RNS.RequestReceipt.FAILED``, ``RNS.RequestReceipt.SENT``, ``RNS.RequestReceipt.DELIVERED``, ``RNS.RequestReceipt.READY``.
"""
Tff7b72return Tff7b72selfTff7b72.Td2a8ffstatus

Tff7b72def Td2a8ffget_progressTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: The progress of a response being received as a *float* between 0.0 and 1.0.
"""
Tff7b72return Tff7b72selfTff7b72.Td2a8ffprogress

Tff7b72def Td2a8ffget_responseTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: The response as *bytes* if it is ready, otherwise *None*.
"""
Tff7b72if Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RequestReceiptTff7b72.Td2a8ffREADYTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffresponse
Tff7b72elseTb4b4b4:
Tff7b72return Tff7b72None

Tff7b72def Td2a8ffget_response_timeTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: The response time of the request in seconds.
"""
Tff7b72if Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RequestReceiptTff7b72.Td2a8ffREADYTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffresponse_concluded_at Tff7b72- Tff7b72selfTff7b72.Td2a8ffstarted_at
Tff7b72elseTb4b4b4:
Tff7b72return Tff7b72None

Tff7b72def Td2a8ffconcludedTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""
:returns: True if the associated request has concluded (successfully or with a failure), otherwise False.
"""
Tff7b72if Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RequestReceiptTff7b72.Td2a8ffREADYTb4b4b4:
Tff7b72return Tff7b72True
Tff7b72elif Tff7b72selfTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RequestReceiptTff7b72.Td2a8ffFAILEDTb4b4b4:
Tff7b72return Tff7b72True
Tff7b72elseTb4b4b4:
Tff7b72return Tff7b72False



Tff7b72class T56d364RequestReceiptCallbacksTb4b4b4:
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffresponse Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8fffailed Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffprogress Tff7b72= Tff7b72None


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────